Let's suppose I need to call an HTTP API PATCH endpoint whose schema for the body is:
{ ..."type": "object","properties": {"propertyOne": { "type": ["string", "null"] },"propertyTwo": { "type": "string" } }}
According to the schema above, all of the following bodies are valid:
{ "propertyOne": null }
{ "propertyTwo": "test" }
{ "propertyOne": "test", "propertyTwo": "test" }
How do I model such a data object in Dart so that when I call .toJson
on that object, it outputs a Map with propertyOne
set to null
if the property was explicitly set to null
, with propertyOne
set to a string if the property was initialized with a string or excludes propertyOne
if no value was specified when initializing the class?
I'm currently using freezed and have a working model for the request if the schema of the API wouldn't include null
as an allowed value. How I model that is:
@freezedclass PatchRequestBody with _$PatchRequestBody { const factory PatchRequestBody({ @JsonKey(includeIfNull: false) String? propertyOne, @JsonKey(includeIfNull: false) String? propertyTwo }) = _PatchRequestBody; factory PatchRequestBody.fromJson(Map<String, dynamic> json) => _$PatchRequestBodyFromJson(json);}
The issue comes when I want different behaviours for when a value is specifically set to null versus when a value is not specified.
For the case above, if I run PatchRequestBody(propertyOne: "test").toJson()
I get { "propertyOne": "test" }
which is great. If I run PatchRequestBody(propertyOne: null).toJson()
it outputs an empty object, which is not great but can be fixed by removing the @JsonKey(includeIfNull: false)
annotation. This unfortunately makes the case where I run PatchRequestBody(propertyTwo: "test").toJson()
output { "propertyOne": null, "propertyTwo": "test" }
which is not what I desire.
I tried looking for some solutions and found this Optional class from a package called quiver but it seems like they advise against not using it anymore.
Otherwise I couldn't really find a way to solve or model this.