Sign in
Log inSign up
Freezed in Flutter

Freezed in Flutter

immutability in Dart

Khadga Bahadur shrestha's photo
Khadga Bahadur shrestha
·Jul 5, 2021·

3 min read

So here we need a lot of data classes while developing a flutter application. So freezed is one of the packages which is used to generate data class and union class. Also, it can be used to serialize and deserialize the JSON data.

So let's integrate freezed in our flutter application. First of all, let's create a flutter project using our own command

flutter create freezed_demo

After that add the following dependencies in the pubspec. yaml file

  • freezed: which is the actual code generator that will generate different methods and fields.
  • builld_runner: the tools to generate the code.
  • freezed_annotation: a package that contains annotations for freezed

Here we need to add freezed and builld_runner in the dev_dependencies section because it is needed while developing an app that will not be available in the production codes. And freezed_annotation to the dependencies section. so after that the resulting pubspec.yaml looks like

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  freezed_annotation: ^0.14.2

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.0.5
  freezed: ^0.14.2

After that run

flutter pub get

Now let's dive into defining a data class using the freezed class. To define a class in freezed we do not need to define the properties but instead of that, we need to define factory constructor. We need to annotate that define class to freezed. so our class looks like

import 'package:freezed_annotation/freezed_annotation.dart';
part 'user.freezed.dart';

@freezed
class User with _$User {
  const User._();

  factory User({
    required String name,
    required String email,
    @Default(true) bool isActive,
  }) = _User; 
}

Here we need to annotate the Person class with @freezed annotation and also define part of that freezed class which means the generated code(We need to run build runner for that) will be the part of the Person class. Here we can assign a default value using Default(value) So now let's run the build_runner so that part file of the defined class will be generated.

flutter pub run build_runner build
//In case of dart only
pub run build_runner build otherwise

Now we can use the Person.

var person = Person(name: 'Khadga', email: '');
print(person.name); // Khadga
print(person.email); // 
print(person.isActive)//true

We can use copyWith copy the property of the object.

var newPerson=person.copyWith(name:'Sakar Subedi');
print(newPerson.name);//Sakar Subedi
print(person.email); // 
print(person.isActive)//true

That is how we define data class using Freezed so let's jump into the Union class.

import 'package:explore_freezed/user.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'result.freezed.dart';

@freezed
class Result with _$Result {
  const Result._();

  factory Result.initial() = _Initial;
  factory Result.success(User user) = _Success;
  factory Result.loading() = _Loading;
  factory Result.error([String? err]) = _Error;
}

As before after adding this code we need to run our build_runner also we can watch the code changes and generate codes. Now, look at how we can use the generated union class in our application.

 _currentState.when(
              initial: () {
               // return some widgets
              },
              success: (user) {
                // return some widgets
              },
              loading: () {
                // return some widgets
              },
              error: (err) {
                 // return some widgets
              },
  ),

Here we need to implement each subclass of the Result so that no condition will be missed.

Freezed class also used with json_serializable to deserialize the JSON data to the Data class. so let's add json_serializable

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.0.5
  freezed: ^0.14.2
  json_serializable: ^4.1.3

After that, we need to add a part file for json_serializable in the data class and add the FromJson method which will deserialize the JSON data.

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user.freezed.dart';

part 'user.g.dart';

@freezed
class User with _$User {
  const User._();

  factory User({
    required String name,
    required String email,
    @Default(true) bool isActive,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> map) => _$UserFromJson(map);

}

Now we can use the fromJson method to deserialize data as

 var _decoded = {'name': 'Khadga Shrestha', 'email': ''};
 var _user = User.fromJson(_decoded);

That's it for now. You can check more about freezed at https://pub.dev/packages/freezed The code repo for this article https://github.com/kodega2016/explore_freezed