json_serializable.dart
json_serializable.dart copied to clipboard
Arg `includeIfNull` is ignored when type is not nullable
Flutter Version
Flutter 3.3.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision e3c29ec00c (6 days ago) • 2022-09-14 08:46:55 -0500
Engine • revision a4ff2c53d8
Tools • Dart 2.18.1 • DevTools 2.15.0
In my case, I have an enum with a null
json value (to avoid a nullable type within my model class)
@JsonEnum()
enum BrandedType {
@JsonValue(1)
restaurant,
@JsonValue(2)
grocery,
@JsonValue(null)
unknown,
}
My Dart model class property:
@JsonKey(includeIfNull: false)
final BrandedType brandedType;
This is the generated code for this property
'branded_type': _$BrandedTypeEnumMap[instance.brandedType]!,
...
const _$BrandedTypeEnumMap = {
BrandedType.restaurant: 1,
BrandedType.grocery: 2,
BrandedType.unknown: null,
};
And this is the json output for this property
"branded_type": null
What's happening in the generator is it's checking for a nullable type on the model class's property type. If the property is not a nullable type (as a Dart object), then it would seem redundant to generate the writeNotNull
method because the value appears to not be nullable (as a serialized object).
This can be validated by making the property's type nullable
// --- model ---
@JsonKey(includeIfNull: false)
final BrandedType? brandedType;
// --- generated code ---
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('branded_type', _$BrandedTypeEnumMap[instance.brandedType]);
...
const _$BrandedTypeEnumMap = {
BrandedType.restaurant: 1,
BrandedType.grocery: 2,
BrandedType.unknown: null,
};
Even when the dart object's value is set to BrandedType.unknown
, there is no json output for this property when resolved with the _$BrandedTypeEnumMap
value, because it resolves to null
.
There is another possible outcome, instead of _$EnumMap[...]
(where the key's value could return a null
value), it would be property.toJson()
(where toJson
could return a null
value). Since we are checking for the null value against the serialized property, and not the Dart model object's current value, the property's type isn't relevant.
A possible fix for this would be to ignore the nullable typing on the property of the Dart object, and generate the writeNotNull
regardless.