Table of Contents

Introduction

Are you willing to build a demo application and learn to work with freezed in your flutter app? Then here’s a flutter freezed example for you! In today’s tutorial, we will learn about the freezed package and how to implement it.

What is Freezed?

The freezed package is a code generator for data classes and union classes that is robust and scalable. In addition, it allows the serialization and deserialization of JSON data.

Rémi Rousselet created Freezed to be a code generator for immutable classes, and you might remember him for the package: provider, riverpod, and hooks.

Flutter Freezed Example: Project Set Up

We will need a few dependencies in pubspec.yaml to get things working. So the first step in our flutter freezed tutorial is to set up the project and install the dependencies.

dependencies:
 flutter:
   sdk: flutter

 freezed_annotation: ^2.0.3
 json_annotation: ^4.0.6


dev_dependencies:
 flutter_test:
   sdk: flutter

 freezed: ^2.0.3+1
 build_runner: ^2.1.11
 json_serializable: ^6.3.1

The following is a rundown of what these dependencies do:

  • freezed_annotation: Annotations for the freezed code-generator.
  • freezed: Code generator with a simple API that can handle complex use-cases.
  • build_runner: It generates model files and watches for any changes, and rebuilds the models accordingly.
  • json_serializable: Annotating Dart classes automatically generates code for converting to and from JSON. The JsonSerializable annotation will generate code for a class to/from JSON.
  • json_annotation: Json_serializable uses annotations to define its operations.

Run the below command to install the dependencies.

flutter pub get
Flutter code

We compare model classes with and without freezed. A model class generation without freezed means the “boilerplate” code isn’t useful in complex applications with a lot of functionality. A model class generation without freezed has a lot of code, and this approach doesn’t scale. Using the package, we can eliminate a lot of boilerplate code.

Leverage World-Class Flutter Talent!
Want to develop a cost-effective Flutter application? Stuck with the question: where can you find proficient developers? Contact Bacancy now and hire flutter developers from us!

Creating Model Classes with freezed

Firstly, you need to create a class that has the @freezed() annotation.

import 'package:freezed_annotation/freezed_annotation.dart';

@freezed
class UserModel{}

Define Class with Mixins

The next step is to define a class with mixins.

import 'package:freezed_annotation/freezed_annotation.dart';

@freezed
class UserModel with _$UserModel{}

Create a Constructor

Now we add a factory method as a constructor with a list of all the arguments/properties. Here we have defined @Default inside the factory method which comes from ‘freezed_annotation’.The @Default annotation is used to set a default value for non-required properties.

import 'package:freezed_annotation/freezed_annotation.dart';

@freezed
class UserModel with _$UserModel {
 const factory UserModel({
   required String firstName,
   required String lastName,
   required String emailId,
   @Default(false) bool isActive,
 }) = _UserModel;

We have now created our constructor. Next, we want to implement fromJson/toJson. In the freezed package, fromJson and toJson are not generated, but it knows what json_serializable is.

Consider this snippet.

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_model.freezed.dart';
part 'user_model.g.dart';

@freezed
class UserModel with _$UserModel {
 const factory UserModel({
   required String firstName,
   required String lastName,
   required String emailId,
   @Default(false) bool isActive,
 }) = _UserModel;

 factory UserModel.fromJson(Map json) => _$UserModelFromJson(json);
}

Here we are done with a UserModel class with freezed code generation.

Generate Code using freezed

The above code snippet shows two lines of code that use part and contain freezed, and these are the ones that let the freezed package know when to generate code for us whenever we run the build_runner.

Now we’re really getting close to the end. Our code generator will generate some errors if we miss something or add a typo.

The next step is to navigate within the terminal to the folder where our project is located and execute the following command.

flutter pub run build_runner build --delete-conflicting-outputs

You will now see new files in your project explorer.

Flutter Generate Code using freezed

You can find the code in the .freezed.dart files. The code generator has added the following to each model class:

A list of all the store arguments/properties inside the factory method was made final

  • the toString() method
  • the == operator
  • the hashCode getter variable
  • the copyWith() method
  • the toJson() method

The data class you have successfully created!

Using the "copyWith" method

The method returns an updated instance with the new properties.

The state is updated when its value changes in state management solutions. State management solutions update the state when its value is changed. Here’s when copyWith comes in handy.

To demonstrate, Assume the UserModel object we created in our state.
The original UserModel object’s values would have been used to create a new UserModel object if we wanted to update our state.

You’ll notice that we get immutability by default. We are also unable to directly assign the properties as expected despite getting the copyWith generated for us.

Using the

The error message indicates that there is a getter for the isActive, but no setter has been created, so value assignment is not possible.

The correct way to assign new values is as follows.

void _updateActiveUser(int index) {
 userModel[index] = userModel[index].copyWith(
     isActive: !userModel[index].isActive);
 setState(() {});
}

// …

child: Column(
 children: [
   ListView.builder(
       shrinkWrap: true,
       itemCount: userModel.length,
       itemBuilder: (BuildContext context, int index) {
         return Container(
           margin: EdgeInsets.only(top: 20, left: 20, right: 20),
           decoration: BoxDecoration(
             color: Colors.grey.shade200,
             borderRadius: BorderRadius.all(Radius.circular(10)),
           ),
           padding: EdgeInsets.all(10),
           child: ListTile(
             title: Text(userModel[index].firstName + " " + userModel[index].lastName),
             subtitle: Text(userModel[index].emailId),
             trailing: Transform.scale(
                 scale: 1,
                 child: Switch(
                   onChanged: (val) {
                     _updateActiveUser(index);
                   },
                   value: userModel[index].isActive,
                   activeColor: Colors.blue,
                   activeTrackColor: Colors.grey.shade700,
                   inactiveThumbColor: Colors.white12,
                   inactiveTrackColor: Colors.grey.shade700,
                 )),
           ),
         );
       }),
 ],
)

We have implemented the following for the user who clicks on the switch under the list view. We will update the value of the isActive user to true or false. Let’s create a function that attaches it to the switch onChange property and just passes in the current index of that item.

On clicking any of the ListTile we will see the below output.

Flutter Freezed Example

Github Repository: Flutter Freezed Example

Here’s the source code of code generation with the freezed package: flutter-freezed-example. Take a look at the code, clone the repository and play around with the code.

In our latest blog we try to cover the Flutter BLoC tutorial with state management using the BLoC pattern.

Conclusion

That’s a wrap. We hope this guide helped you understand how to implement the Freezed package and structure clean, maintainable data models in Flutter.

If you’re planning to build or scale a production-ready application, connect with a trusted Flutter app development company to ensure the right architecture, performance optimization, and long-term scalability for your project.

Vaidehee Vala

Vaidehee Vala

Director of Engineering at Bacancy

Flutter expert and engineering leader crafting high-quality, scalable mobile experiences.

MORE POSTS BY THE AUTHOR
SUBSCRIBE NEWSLETTER

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.