Closed bizk-sato closed 11 months ago
This is currently not supported. It was a limitation of built_value when this library was written originally.
However, built_value supports this now, so we could add an option to ferry_generator to add @BuiltValueSerializer(serializeNulls: true)
to serializers of input fields. ( https://github.com/google/built_value.dart/issues/604 )
This would, however, lead to all fields being included and being sent as null even if they were never set, so it's also not a really good solution.
A complete fix would probably require wrapping all nullable values in something like this.
At the moment, I can only offer you a workaround: Write your own class that implements the G...Var() type and implement your own toJson() where you decide what's included or omitted.
@knaeckeKami Ok, thanks.
Can you provide sample code or how to implements the G...Var()
type and toJson()
method?
I mean at the moment toJson()
in G..Var()
class called, the field_name
propeerty doesn't exist in this
argument in the method. So I don't know how to decide which value is absent or set to null.
You could for example add an additional bool field explictlySetToNull
for every variable that gets set to true to decide wether to include it in the toJson() or not.
I was faced with this issue and ended up with custom serializer:
class PassportSerializer extends JsonSerializer<GupdatePassportVars>
implements StructuredSerializer<GupdatePassportVars> {
@override
GupdatePassportVars fromJson(Map<String, dynamic> json) {
throw UnimplementedError();
}
@override
Map<String, dynamic> toJson(GupdatePassportVars object) {
final passport = object.passport;
final json = object.passport.toJson();
if (passport.series == null) {
json['series'] = null;
}
if (passport.number == null) {
json['number'] = null;
}
return {
"passportId": object.passportId?.value,
"passport": json
};
}
}
Hope it will be fixed soon. Thx for your job!
Thanks for sharing a workaround!
I have a draft solution here: https://github.com/gql-dart/gql/pull/381
I am not sure when I can make it production-ready (especially tests, make this an opt-in feature to avoid breaking changes, and code cleanup).
Extending on what @zombie6888 has posted. Here is a full example:
import 'package:built_value/serializer.dart';
// ignore: implementation_imports
import 'package:gql_code_builder/src/serializers/json_serializer.dart';
import '../../utils/date_utils.dart';
// IMPORT GQueryVars
class QueryVarsSerializer extends JsonSerializer<GQueryVars>
implements StructuredSerializer<GQueryVars> {
@override
GQueryVars fromJson(Map<String, dynamic> json) {
final builder = GQueryVarsBuilder()
..id = json['id']
..nullableField = dateTimeFromJsonValue(json['nullableField']);
return builder.build();
}
@override
Map<String, dynamic> toJson(GQueryVars object) =>
{'id': object.id, 'nullableField': object.nullableField};
// Required override method needed to serialize a null value
// Needs to return a list of all of the key value pairs
@override
Iterable<Object?> serialize(
Serializers serializers,
GQueryVars object, {
FullType specifiedType = FullType.unspecified,
}) =>
['id', object.id, 'nullableField', object.nullableField];
}
Then in build.yaml:
targets:
$default:
builders:
ferry_generator|serializer_builder:
enabled: true
options:
schema: app|lib/graphql/schema.graphql
custom_serializers:
- import: "IMPORT LOCATION"
name: QueryVarsSerializer
I want to update a field with null.
So I did something like below.
field_name
is nullable field in graphql schema.when I submit the request, it doesn't send the
field_name
field. How can I send field with null value?