-
Notifications
You must be signed in to change notification settings - Fork 188
how to deserialize #131
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
Comments
Serialization is done using the https://github.com/google/built_value.dart/blob/master/example/lib/example.dart To get a https://github.com/google/built_value.dart/blob/master/example/lib/serializers.dart Note the expected JSON format does not match what you have in your code snippet. If you want a map-based serializer, you need to also add the StandardJsonPlugin to Serializers, as here: Hope that helps! |
Ok, the hint with the I tried final a = serializers.deserialize(m, specifiedType: const FullType(Account)) as Account; which is pretty cumbersome, there is probably a better way The serializer seems to expect a list instead of a map
|
I just assumed that it accepts this JSON structure. |
That stack trace looks like it's coming from a field deserialization. What types it's expected for each field will depend on the field declarations. It should be possible to deserialize something like that. But, yes, easiest way to see what's expected is to create one and serialize it, either with or without StandardJsonPlugin. |
I just tried to serialize final acc = new Account((b) => b
..profileId = 1
..emailAddress = '[email protected]'
..dob = '1984-02-05');
final x = serializers.serialize(acc, specifiedType: const FullType(Account));
|
Looks like you're right. Previously I debugged in a bit and it failed very early. |
// account.g.dart
Object serialize(Object object,
{FullType specifiedType: FullType.unspecified}) {
var transformedObject = object;
for (final plugin in _plugins) {
transformedObject =
plugin.beforeSerialize(transformedObject, specifiedType);
}
var result = _serialize(transformedObject, specifiedType); // <<<===== is called with |
Without the |
Looks like _typeToSerializer.containsKey(num) = false
_typeToSerializer.containsKey(int) = true |
Yes, was just about to write that :) ... there's no serializer for num. Default serialization will pick the int or double serializer for you, but the StandardJsonPlugin requires an exact match on type type. This is an oversight -- filed an issue Thanks! |
I changed Now this code fails because bool _alreadyHasStringKeys(FullType specifiedType) =>
specifiedType.root != BuiltMap ||
specifiedType.parameters[0].root == String; |
Could you please post the fields from your class? I guess you have a BuiltMap with no type parameters, it needs to be e.g. BuiltMap<String, String>. Note that dynamic types aren't supposed with StandardJsonPlugin, only with default serialization. i.e. the default serialization can serialize BuiltMap<Object, Object>, but StandardJsonPlugin can't. There's an issue open for that #102 |
abstract class Account implements Built<Account, AccountBuilder> {
factory Account([void updates(AccountBuilder b)]) = _$Account;
Account._();
static Serializer<Account> get serializer => _$accountSerializer;
@nullable
int get profileId ;
@nullable
String get emailAddress ;
@nullable
String get dob ;
@nullable
bool get premium ;
@nullable
int get membershipId ;
@nullable
bool get adverts ;
@nullable
double get homeLatitude ;
@nullable
double get homeLongitude ;
@nullable
double get latitude ;
@nullable
double get longitude ;
@nullable
BuiltMap get keyValues ;
} |
Thanks. It's that BuiltMap that's the problem. Built collections anyway always require type parameters -- so you can't create a "BuiltMap" or a "BuiltMap<dynamic, dynamic>'. I'll open an issue to handle this error case better. |
Also not |
Right, has to be BuiltMap<String, Object>. |
I guess it's enough when one of the default JSON serializable types is supported for I don't see a way to support custom types here anyway, except with a custom reviver like supported in |
The default built_value serialization supports any type for Object -- this is the main feature of built_value serialization, in fact :) Unfortunately I don't think Object will work as you want with StandardJsonPlugin. #102 would have to be implemented first -- basically, we add an extra field with the type name. There isn't any fallback to checking the default JSON serialization types; this would be problematic because e.g. there's no distinction between int and double. |
final x = serializers.serialize(acc, specifiedType: const FullType(Account));
final a = serializers.deserialize(m, specifiedType: const FullType(Account)) as Account; is quite cumbersome. Any suggestion how to make this easier to use? |
Just saw, |
With the default serialization you don't need "specifiedType". With StandardJsonPlugin you do, and it's currently a bit ugly, I agree. You could wrap the serialization: Object serialize(Object object) { but the deserialize is a bit harder, you could wrap it to look like "deserialize(m, Account) as Account". Re: the extra field, yes, that's a good point. I hadn't thought about supporting "jsony maps". One way would be to add a JsonPrimitive class that can deserialize from any JSON primitive. What do you think? (This would start to look a lot a Java Json library.) |
final x = serializers.serialize(acc);
final x = serializers.serialize(acc, specifiedType: const FullType(Account)); works fine though. |
Not sure in detail how you imagine that, but sounds good ;-) |
Right now with StandardJsonPlugin you'll need to wrap the "serialize" method with something that creates the FullType for you. (With the default serialization, you don't to do anything, it just works) The reason there's mismatch here is because built_json was originally designed to be the serialization on both sides of the pipe -- i.e. you use it on the server in the VM and on the client with dart2js. Only later did it transpire that people would very much like to have interop with other json things :) ... and so StandardJsonPlugin was added last month. It's a bit rough around the edges -- thanks for pointing out a few major gaps :) I'll create an issue for supporting Map<String, dynamic> somehow. |
I think my questions to this topic are answered. Thanks a lot! |
FYI #146 adds JsonObject and "serializeWith/deserializeWith" methods for easier serialization/deserialization when you know the type. See the example here: Basically you do:
|
@davidmorgan do I need to import
|
@techyrajeev Yes, you'll need to import it anywhere it's used. |
Oh I thought It will be auto injected when I run This scenario can also be auto generated since we just need to add the import to any model declared in |
|
I find it hard to find information about how to deserialize
I'd expect something like
but that doesn't work
The text was updated successfully, but these errors were encountered: