json_serializable.dart icon indicating copy to clipboard operation
json_serializable.dart copied to clipboard

Attributes which aren't in the constructor aren't serialized

Open joostlek opened this issue 5 years ago • 4 comments

Hey,

I found an issue whilst working on my flutter app.

(Bit of context first) I have an Activity, it's a base model, containing a DateTime, Firestore DocumentID, user and a type. That type is an enum, and currently I have ~11 activities, all inheriting the Activity class. And adding more attributes. This all works.

To deserialize the activities, I check on the Type attribute, and get the right class to construct the Activity with.

But because the Type of each different class is the same, I didn't include it as an argument in the constructor (When I am constructing a CreateUser, I don't want to send the type again because if I create a CreateUser, I want a CreateUser, not a CreateUser with a RemoveUser type)

So all the extended models have a constructor with a super constructor, and that type is not passed as argument but is just in the super call (CreateUser(.....) : Super(Activities.CreateUser).

This would create an object with type: CreateUser.

But when I am Serializing, it doesnt Serialize the type attribute. So when it's stored in Firestore it doesn't show what Type it is, thus I can't deserialize it, because I don't know what constructor I need to use.

I fixed this by just putting a , [Activities type] to the constructor.

Relevant code is in GitHub.com/joostlek/eros (The lib/models/activity/Activity is the main class)

Thanks Keep up the great work you re doing

joostlek avatar Aug 05 '18 11:08 joostlek

That's a tricky one. I could imagine adding a special-case annotation for a field – something like "serialize me, even though I'm not in a ctor".

An interesting feature request. Sounds like you have a work-around.

kevmoo avatar Aug 06 '18 02:08 kevmoo

Yes, the workaround works, but having it working like intended is also a nice to have 😂

joostlek avatar Aug 06 '18 11:08 joostlek

I have a very similar situation. I want to have a 'type' field that is to be saved in the output JSON when I serialize an object, so I can read that field when deserializing so I know what type class to deserialize it as. My current workaround is adding an extra line to the toJson() method to manually add that missing attribute..

I previously mentioned this in a related issue, #24 It is essentially the same use case and probably the same solution would fix both of these issues.

dominickj-tdi avatar Apr 29 '19 20:04 dominickj-tdi

Mentioned this here, but we have the exact same use case, we're sharing data classes on the backend, and we need to embed a type. https://github.com/google/json_serializable.dart/issues/891

The work around of adding an optional field is not great, as it's mis-leading code. You're allowing the type can be overridden, which is a bug vector and could confuse some future developer.

esDotDev avatar Jun 09 '21 18:06 esDotDev

Duplicate of #569

Trying to align all of these requests into one place!

kevmoo avatar Nov 17 '22 23:11 kevmoo

I have a (draft) PR out on this. I'd LOVE (early) feedback about if this works for what folks need here: https://github.com/google/json_serializable.dart/pull/1256

I still need to do some documentation and testing...

kevmoo avatar Nov 22 '22 01:11 kevmoo