카테고리 없음

[flutter] freezed toJson생성하기, nested list serialization

뚜개 2024. 11. 22. 11:00

freezed로 생성한 객체 안에 list가 있는데

자동으로 toJson이 생성되지 않았다.

freezed문서를 살펴보다보니

https://pub.dev/packages/freezed#fromjsontojson

[freezed | Dart package

Code generation for immutable classes that has a simple syntax/API without compromising on the features.

pub.dev](https://pub.dev/packages/freezed#fromjsontojson)

Note:
In order to serialize nested lists of freezed objects, you are supposed to either specify a @JsonSerializable(explicitToJson: true) or change explicit_to_json inside your build.yaml file (see the documentation).

마지막에 explicitToJson을 켜야한다고 써있다,.

https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/explicitToJson.html

[explicitToJson property - JsonSerializable class - json_annotation library - Dart API

explicitToJson property bool? explicitToJson final If true, generated toJson methods will explicitly call toJson on nested objects. When using JSON encoding support in dart:convert, toJson is automatically called on objects, so the default behavior (explic

pub.dev](https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/explicitToJson.html)

If true, generated toJson methods will explicitly call toJson on nested objects.

When using JSON encoding support in dart:convert, toJson is automatically called on objects, so the default behavior (explicitToJson: false) is to omit the toJson call.

Example of explicitToJson: false (default)

Map<String, dynamic> toJson() => {'child': child};

Example of explicitToJson: true

Map<String, dynamic> toJson() => {'child': child?.toJson()};

설명을 보면 nested object에 대해서도 toJson을 호출해준다고 써져있다.

이렇게 코드 위에 annotation을 추가해도 되고

@JsonSerializable(explicitToJson: true)
class Person {
  /// The generated code assumes these values exist in JSON.
  final String firstName, lastName;

  /// The generated code below handles if the corresponding JSON value doesn't
  /// exist or is empty.
  final DateTime? dateOfBirth;

  Person({required this.firstName, required this.lastName, this.dateOfBirth});

  /// Connect the generated [_$PersonFromJson] function to the `fromJson`
  /// factory.
  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  /// Connect the generated [_$PersonToJson] function to the `toJson` method.
  Map<String, dynamic> toJson() => _$PersonToJson(this);
}

build.yaml 파일 생성후 디폴트 값을 세팅해도 된다.


targets:  
  $default:  
    builders:  
      json\_serializable:  
        options:  
          # Options configure how source code is generated for every  
          # \`@JsonSerializable\`-annotated class in the package.  
          #  
          # The default value for each is listed.  
          any\_map: false  
          checked: false  
          constructor: ""  
          create\_factory: true  
          create\_field\_map: false  
          create\_json\_keys: false  
          create\_per\_field\_to\_json: false  
          create\_to\_json: true  
          disallow\_unrecognized\_keys: false  
          explicit\_to\_json: false  
          field\_rename: none  
          generic\_argument\_factories: false  
          ignore\_unannotated: false  
          include\_if\_null: true

jsonSerializable이랑 freezed anootiation을 둘 다 쓸때는 이렇게 써야한다.

@freezed
class Example with _$Example {
  @JsonSerializable(explicitToJson: true)
  factory Example(@JsonKey(name: 'my_property') SomeOtherClass myProperty) = _Example;

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