Skip to content

How to deserialise top-level list of items #565

Closed
@votruk

Description

@votruk

For example I have json file:

[
  {
    "name": "test1",
    "result": "success"
  },
  {
    "name": "test2",
    "result": "fail"
  }
]

How can I deserialise it properly?

I understand that possible way to do it is to wrap this list into top-level object with a key. Something like that:

{
  "list_of_items": [
    {
      "name": "test1",
      "result": "success"
    },
    ...
  ]
}

But I have multiple files with such structure so I wonder if there any other ways to handle it?

Activity

changed the title [-]Deserialise top-level list of items[/-] [+]How to deserialise top-level list of items[/+] on Jan 9, 2019
davidmorgan

davidmorgan commented on Jan 9, 2019

@davidmorgan
Collaborator

You could iterate over the top level list calling serializers.deserialize on each inner map. You'll need to use StandardJsonPlugin to get it to accept the map format instead of the default list format; the third heading here:

https://medium.com/dartlang/moving-fast-with-dart-immutable-values-1e717925fafb

self-assigned this
on Jan 9, 2019
votruk

votruk commented on Jan 11, 2019

@votruk
Author

Thanks for response - the approach you have suggested works well.
In case anybody needs this functionality I leave here code snippet of how to handle this situation (code should be placed in serializers.dart file):

Serializers standardSerializers = (serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();

T deserialize<T>(dynamic value) =>
    standardSerializers.deserializeWith<T>(standardSerializers.serializerForType(T), value);

BuiltList<T> deserializeListOf<T>(dynamic value) =>
    BuiltList.from(value.map((value) => deserialize<T>(value)).toList(growable: false));

So if you have json file

[
  {
    "name": "test1",
    "result": "success"
  },
  {
    "name": "test2",
    "result": "fail"
  }
]

And built value class:

import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';

part 'test_class.g.dart';

abstract class TestClass implements Built<TestClass, TestClassBuilder> {

  String get name;
  String get result;

  TestClass._();
  
  factory TestClass([updates(TestClassBuilder b)]) = _$TestClass;
  
  static Serializer<TestClass> get serializer => _$testClassSerializer;
  
}

You can use method deserializeListOf from above as:

import 'package:path_to_your_serializers_file/serializers.dart';

final BuiltList<TestClass> listOfTestClasses = deserializeListOf<TestClass>(jsonFile);
anqit

anqit commented on May 20, 2022

@anqit

I have two issues with the above code snippet:

  1. First I get the error A value of type 'T?' can't be returned from the function 'deserialize' because it has a return type of 'T'. I can fix this by adding ! :
T deserialize<T>(dynamic value) =>
    standardSerializers.deserializeWith<T>(standardSerializers.serializerForType(T), value)!;
//                                                                     add null check here ^
  1. After that "fix" (Intellij now has a warning about that null check), I get the following error with I haven't been able to figure out:
T deserialize<T>(dynamic value) =>
    standardSerializers.deserializeWith<T>(standardSerializers.serializerForType(T), value)!;
//                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// `The argument type 'Serializer<dynamic>?' can't be assigned to the parameter type 'Serializer<T>'`

Any thoughts? My guess is later versions of Dart have more stringent type/null checking? Other ways to de/serialize collections of built values?

EDIT:
Adding the following hacky "solution" may work (compiles at least, haven't run the code yet), I'm wondering if there's a more type-safe way to do this still:

T deserialize<T>(dynamic value) =>
    standardSerializers.deserializeWith<T>(standardSerializers.serializerForType(T) as Serializer<T>, value)!;
//                                                                                  ^^^^^^^^^^^^^^^^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @davidmorgan@anqit@votruk

      Issue actions

        How to deserialise top-level list of items · Issue #565 · google/built_value.dart