Flutter, Freezed: Set Class as default value

1,873

Solution 1

I have had the same wish and unfortunately more people have thought about it. From what I could find out it is not possible and the reason is JsonSerializable and not Freezed per se.

Check this Q&A on Github: https://github.com/rrousselGit/freezed/issues/149#issuecomment-616083333

I guess the solution with adding @JsonKey that you wrote about is something like this (OP's answer to himself)? https://github.com/rrousselGit/freezed/issues/149#issuecomment-616098286

Solution 2

Starting from freezed 2, this will work

@freezed
class Cart with _$Cart {
  const factory Cart({
    @Default([]) List<int> items,
  }) = _Cart;

  factory Cart.fromJson(Map<String, dynamic> json) => _$CartFromJson(json);
}

@freezed
class User with _$User {
  const factory User({
    @Default(Cart()) Cart cart,
  }) = _User;

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

Then Cart.fromJson({}).items or User.fromJson({}).cart.items will give you []


Before freezed 2, use this workaround:

@Default(const Cart()) @JsonKey(fromJson: _CartFromNullableJson) Cart cart,
Cart _CartFromNullableJson(Map<String, dynamic>? json) =>
    json == null ? Cart() : Cart.fromJson(json);
Share:
1,873
mrgnhnt96
Author by

mrgnhnt96

I love Flutter!

Updated on December 01, 2022

Comments

  • mrgnhnt96
    mrgnhnt96 over 1 year

    I have a User class which contains a Purchase class. I want to make it non-nullable, but not required. So this means that I would need to set a default value.

    I have no required fields in the sub-class (Purchase), and have provided default values.

    When I run build_runner I get an error saying that the default value must be a literal. And I understand that the default value must be a constant.

    [SEVERE] json_serializable:json_serializable on lib/domain/user/user.model.dart:
    
    Error with `@JsonKey` on `purchase`. `defaultValue` is `_$_Purchase`, it must be a literal.
    package:clean_simple_eats/domain/user/user.model.freezed.dart:323:18
        ╷
    323 │   final Purchase purchase;
        │                  ^^^^^^^^
        ╵
    

    I realize that I can create my own toJson and fromJson with @JsonKey, but I would prefer to let freezed generate the code. Is there a way to achieve this with the most recent version of freezed (v0.14.2)?

    User Model File:

    import 'package:clean_simple_eats/features/purchase/domain/purchase.model.dart';
    import 'package:freezed_annotation/freezed_annotation.dart';
    
    part 'user.model.freezed.dart';
    part 'user.model.g.dart';
    
    @freezed
    class CUser with _$CUser {
      const CUser._();
    
      factory CUser({
        @Default(Purchase()) Purchase purchase,
      }) = _CUser;
    
      factory CUser.fromJson(Map<String, dynamic> json) => _$CUserFromJson(json);
    }
    

    Purchase File:

    import 'package:freezed_annotation/freezed_annotation.dart';
    
    part 'purchase.model.freezed.dart';
    part 'purchase.model.g.dart';
    
    @freezed
    class Purchase with _$Purchase {
      const factory Purchase({
        @Default(false) bool isSubscribed,
      }) = _Purchase;
    
      factory Purchase.fromJson(Map<String, dynamic> json) =>
          _$PurchaseFromJson(json);
    }