Reputation: 277
Is it possible to use json_serializable and have different key names for same field for toJson and fromJson.
ex json-data:
{
"idUser": 123,
/// some other fields
}
incoming json_data from another APIs
{
"id" : 123,
/// some other fields
}
@JsonSerializable()
class Id extends INetworkModel<Id> {
Id(this.idUser);
final int? idUser;
@override
Id fromJson(Map<String, dynamic> json) => _$IdFromJson(json);
@override
Map<String, dynamic>? toJson() => _$IdToJson(this);
}
for that particular id field, I want to map it as idUser for toJson and id as fromJson.
based on what I saw for json_serializable docs it's possible to manipulate field values with custom toJson and fromJson methods but didn't see any other option to manipulate key names in JSON based on the method.
I would be very glad if someone enlightens me thanks ahead!
Upvotes: 2
Views: 890
Reputation: 19
The readValue
parameter in JsonKey
can be used to differentiate the key used for fromJson
from the main one which is used for toJson
.
@JsonSerializable()
class Id extends INetworkModel<Id> {
Id(this.idUser);
// Create a static method for `readValue`
static int? readId(Map<dynamic, dynamic> json, String name) {
// When used by `idUser` in this context, `name` would be "idUser".
// We can ignore that and just grab a value from the key that we want.
return json["id"];
}
// "idUser" or whatever name given in the `JsonKey`'s `name` parameter will still be used for `toJson`.
@JsonKey(readValue: readId)
final int? idUser;
@override
Id fromJson(Map<String, dynamic> json) => _$IdFromJson(json);
@override
Map<String, dynamic>? toJson() => _$IdToJson(this);
}
Upvotes: 0
Reputation: 197
Not recommended, however you can do
Go to yourfile.g.dart
part of 'yourfile.dart';
as you stated that I want to map it as idUser for toJson and id as fromJson.
Id _$IdFromJson(Map<String, dynamic> json) => Id(
idUser: json['id'] as int,
// your rest of fields
);
Map<String, dynamic> _$IdToJson(Id instance) => <String, dynamic>{
'id': idUser,
// your rest of fields
};
Upvotes: 0
Reputation: 1026
An alternative approach to having 2 sources for the same property:
Parse both as nullable, and have a getter to retrieve the value. Something like:
@JsonSerializable()
class Id extends INetworkModel<Id> {
Id(this.idUser, this.id);
final int? idUser;
final int? id;
int? get theUserId => id ?? isUser;
@override
Id fromJson(Map<String, dynamic> json) => _$IdFromJson(json);
@override
Map<String, dynamic>? toJson() => _$IdToJson(this);
}
Upvotes: 1