I have nested classes InventoryResult and Item that I want to read/write with json files, and the generated code by json_annotation does not map Item list in the toJson() method; curiously handling is totally fine for fromJson() method. Below are my 2 classes:
@JsonSerializable()
class InventoryResult {
List<Item> results;
int number;
int offset;
int totalResults;
InventoryResult({required this.results, required this.number, required this.offset, required this.totalResults});
factory InventoryResult.fromJson(Map<String, dynamic> json) => _$InventoryResultFromJson(json);
Map<String, dynamic> toJson() => _$InventoryResultToJson(this);
}
@JsonSerializable()
class Item {
int id;
String productName;
Item(
{required this.id,
required this.productName});
factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json);
Map<String, dynamic> toJson() => _$ItemToJson(this);
}
and Inventory's generated fromJson() and toJson() methods differ oddly:
InventoryResult _$InventoryResultFromJson(Map<String, dynamic> json) =>
InventoryResult(
results: (json['results'] as List<dynamic>)
.map((e) => Item.fromJson(e as Map<String, dynamic>))
.toList(),
number: (json['number'] as num).toInt(),
offset: (json['offset'] as num).toInt(),
totalResults: (json['totalResults'] as num).toInt(),
);
Map<String, dynamic> _$InventoryResultToJson(InventoryResult instance) =>
<String, dynamic>{
'results': instance.results, //INCORRECT NESTED CLASS HANDLING HERE
'number': instance.number,
'offset': instance.offset,
'totalResults': instance.totalResults,
};
Naturally as a result, when I read from Json everything is correct, when I write to json it just writes as 'Instance' instead of correctly parsing Item object. I have json_annotation and json_serializable also up to date and totally stumped. Can it be related to that I added Item's toJson() method later in the project? I have re-built many times after that, also tried deleting generated g.dart files altogether as well. Both class files import each other and json_annotation package, and the g.dart files. Item's generated g.dart file appears correct with fromJson() and toJson() methods. I cannot find the issue.
Add the explicitToJson: true
flag to the @JsonSerializable
annotation of the outer class InventoryResult
:
@JsonSerializable(explicitToJson: true)
class InventoryResult {
// Your existing class fields and methods
}
This ensures that the generated toJson
method will explicitly call toJson
on nested objects like Item
.
Now, the generated _$InventoryResultToJson
method will look like this:
Map<String, dynamic> _$InventoryResultToJson(InventoryResult instance) =>
<String, dynamic>{
'results': instance.results.map((e) => e.toJson()).toList(), // Correctly serializes each Item
'number': instance.number,
'offset': instance.offset,
'totalResults': instance.totalResults,
};