Skip to content

toJson and fromJson work differently with nested objects #1573

@CarmeloBeeapp

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),
};

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