I have an API that's returning a list of objects...

[{}, {}, {}, ...]

I already have a defined and working built_value model for each object. However, now I need to deserialize the list.

I currently am trying something like this:

 List<Map<String, dynamic>> json = JSON.decode(DEMO_TASK);
 json.expand<Task>((Map<String, dynamic> map) => _serializers.deserializeWith<Task>(Task.serializer, map));

However, that causes issues since it says _serializers.deserializeWith return type Task isn't an Iterable<Task> as defined by the closure.

How do I go about deserializing the list. I'm sure I'm missing something super basic.


Solution 1: James Gilchrist

Yup. I missed something basic. I was thinking I was using a stream, but since it's a list you just have to use the .map function on a list.

List<Map<String, dynamic>> json = JSON.decode(DEMO_TASK);
    List<Task> tasks = json.map<Task>((Map<String, dynamic> map) => _serializers.deserializeWith<Task>(Task.serializer, map)).toList();


Solution 2: Ilia Kurtov

In case you want to have more general approach you can use this code snippet: 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>(json);