-
Notifications
You must be signed in to change notification settings - Fork 183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is it possible to distinguish between absent (no value) and null when serializing? #1123
Comments
Please try tagging your https://pub.dev/documentation/built_value/latest/built_value/BuiltValueSerializer-class.html and setting |
Yes I tried that (it's already in the code I posted above). However it will always print |
I'm afraid that's not possible; the builder already uses |
Thanks for your answer. Do you think that's a feature that could be developed? I think the package freezed managed to do it. although I haven't looked into the details yet. I'd be keen on helping. |
Likely not: it would complicate the current implementation for not much benefit. I'm curious, why do you need this behaviour? Maybe there's another way to achieve what you're trying to do. Thanks. |
It's because of the issue I linked at the top. I use ferry to generate graphql queries / mutations and ferry uses built_value to serialize the variables of a mutation before sending it to the server. For example: if I have these graphql objects: type TodoItem {
id: ID!
title: String!
dueDate: Date
}
# title and dueDate are nullable in the input to only send what you want to update
input TodoInput {
id: ID!
title: String
dueDate: Date
} If I want to only update the title of a Todo, I can just send the id and the title and leave the dueDate absent. If we can't differentiate between null and absent, either:
There are some workarounds like sending an array instead of a value and consider that if the array is absent it means no update vs if the array is empty it means you want to set the field to null etc. But I wish there was a more direct way to do things. |
Ah, yes, I'm familiar with that kind of usage. Effectively you want another layer of I would like to support that somehow but I haven't figured a way for it to fit in nicely with what we have already. I suspect the 'correct' way might involve a third generated class: in addition to I suspect this is too big a problem for me to get to any time soon, unfortunately. |
I experimented somewhat successfully with this in ferry_generator, a code gen that generates graphql classes that use built_value. At the moment I introduce a new
At the moment I generate a custom serializer for any type that has such a Value type, but I'd like to avoid that if possible since I feel this is tricky to get right in all corner cases and built_value has figured that out pretty well in the last 8 years ;). Do you think it makes sense to add support for this directly in buit_value via the generated serializers? Or maybe add a Plugin like StandardJsonPlugin that understand such a (reference: gql-dart/gql#381 ) |
How does the Possibly there could be support for such a boolean field indicating whether the null is present. I'd have to think about it though :) |
At the moment I did it this way: Value is just a wrapper around a nullable field: class Value<T extends Object> {
final T? _value;
T? get value => _value;
/// Create a (present) value by wrapping the [value] provided.
const Value(T? value) : _value = value;
When there is an optional Value<String>? get field So now there are three possible states:
So I use the nullability of the wrapper to represent the absent state. It works, but I'm not happy with it in its current form because it breaks the composability of nested builders and it requires custom serializers, so if I ship it, I'll probably come up with something else. |
I have now released a first dev version of this feature in ferry_generator. This is done be wrapping each nullable field in a "Value" class https://github.com/gql-dart/gql/blob/master/codegen/gql_tristate_value/lib/src/value.dart This is a sealed class with two possible types, This allows us to represent three states:
in order to make this work, each value - field has to be initialized to An example of Built-Class with value types and serializer can be found here: Is there any interest in adding a feature like this in built_value directly? |
Thanks Martin :) Did I understand correctly that the Serializer of each class with a field of type I wonder if you could implement this with a https://pub.dev/documentation/built_value/latest/serializer/SerializerPlugin-class.html it gets called during serialization with information about the types, and can modify the data and response. So maybe it can make the changes needed for all types. |
Yes, currently it generates a custom Serializer for every Built class that handles wrapping/unwrapping the e.g. if (_$episodevalue case _i1.PresentValue(value: final _$value)) {
result.add('episode');
result.add(serializers.serialize(_$value,
specifiedType: const FullType(_i2.GEpisode)));
}
I did really not look into the I'll check it out and see if I can get this working. |
Let's say I have a SimpleValue class with a nullableString:
I would like to be able to have this behaviour when serializing to JSON:
Is it possible?
The text was updated successfully, but these errors were encountered: