Supporting multiple keys for the same field during deserialization
sabinbajracharya opened this issue · 2 comments
Problem statement:
I have a model called "Calendar" which needs to parse either the following json
{
"cid": "101",
"ut": "20230715",
"cb": "admin@admin.com",
"st": 1
}
or the following one depending on some use cases
{
"calendar_id": "101",
"updated_time": "20230715",
"created_by": "admin@admin.com",
"status": 1
}
Basically the value will be the same only difference is the key. The reason for this is that the "Calendar" model has lots of fields and this data is in a file which is kept in the asset folder of the application. So, the fields are shortened to reduce some space taken by the file.
For deserialization, I need to be able to parse the json with both possible keys for the same value. But for serialization I only need the keys shown in the second json so no problem with serialization.
The interim solution that I am using is the following:
- Extend the "_$CalendarModelSerializer" generated by built_value and override the "deserialize" method to add two cases for each value.
- Use this extended serializer to decode the json but use the originally generated serializer to serialize the model.
class _$CalendarModelWithMultipleKeySerializer extends _$CalendarModelSerializer {
@override
CalendarModel deserialize(
Serializers serializers, Iterable<Object?> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = CalendarModelBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current! as String;
iterator.moveNext();
final Object? value = iterator.current;
switch (key) {
case 'calendar_id':
case 'cid':
result.calendarId = serializers.deserialize(value,
specifiedType: const FullType(String))! as String;
break;
case 'status'
case 'st':
result.status = serializers.deserialize(value,
specifiedType: const FullType(int))! as int;
break;
case 'created_by':
case 'cb':
result.createdBy = serializers.deserialize(value,
specifiedType: const FullType(String))! as String;
break;
case 'updated_time':
case 'ut':
result.updatedAt = serializers.deserialize(value,
specifiedType: const FullType(DateTime))! as DateTime;
break;
}
}
return result.build();
}
}
So, is there any possible way to add two "wireName" for the same field? Or any workaround so that I don't have to manually add two cases everytime I need to change or add a new field.
I think that this PR
exactly does what you want by adding an oldWireNames
setting that can list multiple alternative wire names for deserializing a field. It does not let you use alternatives for serializing.
--but there hasn't been any update there in a while; let me ask. Thanks.
@davidmorgan That's exactly what I am looking for and it looks like the PR is almost done. Thanks!