Skip to content

toJson and fromJson work differently with nested objects #1573

Description

@CarmeloBeeapp

The two methods are working in different ways

for example using these classes:

@JsonSerializable()
class Parent {
  String name;
  String surname;
  Child child1;
  Child child2;

  factory Parent.fromJson(Map<String, dynamic> json) => _$ParentFromJson(json);

  Parent({required this.name, required this.surname, required this.child1, required this.child2});

  Map<String, dynamic> toJson() => _$ParentToJson(this);
}

@JsonSerializable()
class Child {
  String name;
  String surname;

  factory Child.fromJson(Map<String, dynamic> json) => _$ChildFromJson(json);

  Child({required this.name, required this.surname});

  Map<String, dynamic> toJson() => _$ChildToJson(this);
}

the fromJson methods are correctly:

Parent _$ParentFromJson(Map<String, dynamic> json) => Parent(
  name: json['name'] as String,
  surname: json['surname'] as String,
  child1: Child.fromJson(json['child1'] as Map<String, dynamic>),
  child2: Child.fromJson(json['child2'] as Map<String, dynamic>),
);

Child _$ChildFromJson(Map<String, dynamic> json) =>
    Child(name: json['name'] as String, surname: json['surname'] as String);

instead the toJson methods are the following

Map<String, dynamic> _$ParentToJson(Parent instance) => <String, dynamic>{
  'name': instance.name,
  'surname': instance.surname,
  'child1': instance.child1,
  'child2': instance.child2,
};

Map<String, dynamic> _$ChildToJson(Child instance) => <String, dynamic>{
  'name': instance.name,
  'surname': instance.surname,
};

with nested objects the toJson method doesn't convert the object in json.

As workaround at the moment is required to define a custom method to parse the nested object and pass it in the annotation

@JsonSerializable()
class Parent {
  String name;
  String surname;
  @JsonKey(toJson: childToJson)
  Child child1;
  @JsonKey(toJson: childToJson)
  Child child2;

  factory Parent.fromJson(Map<String, dynamic> json) => _$ParentFromJson(json);

  Parent({required this.name, required this.surname, required this.child1, required this.child2});

  Map<String, dynamic> toJson() => _$ParentToJson(this);
}
Map<String, dynamic> _$ParentToJson(Parent instance) => <String, dynamic>{
  'name': instance.name,
  'surname': instance.surname,
  'child1': childToJson(instance.child1),
  'child2': childToJson(instance.child2),
};

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions