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

Looking into setter-only or getter-only

Open kevmoo opened this issue 6 years ago • 8 comments

  • I guess you could have a setter-only for just fromJson case.
  • Don't try to create a write to a property that's only a setter
  • etc...

kevmoo avatar Jul 23 '17 03:07 kevmoo

Hello, I'm not sure wheter to open new issue or just comment this one. I have a model on server side where I have two getters which return values base on other properties and I want them called from _$ModelToJson(). I have no setters (no reason to have them).

Model {
  @JsonKey(name: 'holder')
  String holder;
  @JsonKey(name: 'source')
  String source;
  @JsonKey(name: 'symbol')
  String get symbol => holder == 'owner' ? 'O' : 'G';
  @JsonKey(name: 'description')
  String get description => holder == 'owner' ? 'Owner' : 'Guest';
}

and I expect _$ModelToJson to contain

Map<String, dynamic> _$ModelToJson(Model instance) => <String, dynamic>{
      'holder': instance.holder,
      'source': instance.source,
      'symbol': instance.symbol,
      'description': instance.description
}

but symbol and description are not included until I create setters, so then setters are called from $_ModelFromJson(Map<String, dynamic> json) { ... }. Simple workaround is to create setters which do nothing, but I suppose that's not correct. Vice versa I would expect that when I only have setters the _$ModelFromJson() should call them and _$ModelToJson() should ignore these properties.

edlman avatar Apr 08 '19 08:04 edlman

@edlman do you need to create this class from Json?

If not, just put @JsonSerializable(createFactory: false) on the class and you should be good!

kevmoo avatar Apr 08 '19 22:04 kevmoo

@kevmoo, yes I need to create this class from json (or other map, e.g. database Row). It's on the server side, some data are fetched from PgSQL to the object using _$ModelFromJson(PgRow as Map) and then passed as JSON to a client using _$ModelToJson(). And I need to pass some server generated values from getters to the client.

edlman avatar Apr 09 '19 07:04 edlman

So you want to create this class from JSON in one shape, but have it generate JSON in another shape?

kevmoo avatar Apr 09 '19 14:04 kevmoo

Practically yes. When I use getters I expect to have simplier JSON on input to _$ModelFromJson (either from DB or from client). On output from $_ModelToJson I expect richer JSON containing values not only from variables but also from getters. And vice versa when I use setters I expect richer JSON on input to $_ModelFromJson, I can process these values in setters for whatever I need. On output from _$ModelFromJson I expect simplier JSON contaning only values from variables. As I explained on my example code, I have some values generated by getters on server side. On client side I process these values from JSON (and I would like to process them with setters eventually). I know I can move getters to client side and send only simplier JSON from server, but the server API will be used by other platforms and 3rd party apps, so I want to do all logic on server and send complete data to the clients. On server I expect input JSON (from DB or client) { "holder": "owner", "source": "plan" } but on output it will send to client { "holder": "owner", "source": "plan", "symbol": "O", "description": "Owner" } where symbol and description are valued from getters. On client I expect input JSON { "holder": "owner", "source": "plan", "symbol": "O", "description": "Owner" } where all values are processed normally.

edlman avatar Apr 09 '19 15:04 edlman

I could also see something like this being useful. Here is my use case:

The JSON data is being stored in a couchdb database. I have a "type" field in some JSON objects to differentiate between different variations of similar objects. I use a factory constructor in an abstract class when pulling data from the database and read this "type" field and determine which type of object to create, which then calls the fromJson() constructor of that object.

So, when I'm calling fromJson() the created object doesn't need to set the type field. However, when I call toJson() it should include the "type" field with the appropriate value. That way, I can save it to the database and, when I read it again, know what type to de-serialize it as.

dominickj-tdi avatar Apr 24 '19 17:04 dominickj-tdi

I should note what I'm doing now is just adding one extra line of code to the toJson() function to manually add the type feild and that solution is okay for me, but it would be nice to have an included solution.

Also, a use-case for a setter only field: Say we had a Contact object with a firstname and lastname field, as well as a getter/setter feild just called name. We wouldn't need name in the output JSON data since it would be redundant, the same data would be in there twice. However, if we get sent JSON data to de-serialize, and it contains name instead of firstname and lastname, we should be able to just call the setter and have it parse that feild into firstname and lastname.

dominickj-tdi avatar Apr 24 '19 17:04 dominickj-tdi

I have exactly the same case as well.

My model has a 'typeId' as a getter only property. I want the velue to be deserialised but don't need ot in fromJson factory.

Any solution?

aboo avatar Jan 01 '21 09:01 aboo

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