Skip to content

Support custom Iterator/List types #593

Closed
@MisterJimson

Description

@MisterJimson

I'm looking at how it can be possible to support Iterators that are not supported by default in
json_serializable.

Examples are ObservableList from Mobx or BuiltList from built_collection.

I am able to implement a basic solution, however it requires a JsonConverter for every type you plan to use with those Lists.

One example here: https://mobx.pub/guides/json shows that it works, but that Converter only works for ObservableList<Todo>, not ObservableList<T>. (And of course T in this case is either a basic JSON type or has a toJson method).

Another example from my codebase using BuiltList.

class BuiltListConverterNote
    implements JsonConverter<BuiltList<Note>, List<Map<String, dynamic>>> {
  const BuiltListConverterNote();

  @override
  BuiltList<Note> fromJson(List<Map<String, dynamic>> json) =>
      BuiltList.of(json.map((x) => Note.fromJson(x)));

  @override
  List<Map<String, dynamic>> toJson(BuiltList<Note> list) =>
      list.map((x) => x.toJson()).toList();
}

@JsonSerializable()
class ServiceOrder {
  @BuiltListConverterNote()
  final BuiltList<Note> notes;
}

The above works, but again I need to create that JsonConverter for every type like Note I want to use.

I'm looking for something like the following.

final factories = <Type, Function>{
  Note: (Map<String, dynamic> json) => Note.fromJson(json)
};

T make<T>(Type type, Map<String, dynamic> x) {
  return factories[type](x);
}

class BuiltListConverter<T>
    implements JsonConverter<BuiltList<T>, List<Map<String, dynamic>>> {

  const BuiltListConverter();

  @override
  BuiltList<T> fromJson(List<Map<String, dynamic>> json) =>
      BuiltList.of(json.map((x) => make(T, x)));

  @override
  List<Map<String, dynamic>> toJson(BuiltList<T> list) =>
      list.map((x) => (x as dynamic).toJson()).toList();
}

@JsonSerializable()
class ServiceOrder {
  @BuiltListConverter()
  final BuiltList<Note> notes;
}

This currently doesn't work.

Error running JsonSerializableGenerator
Could not generate `fromJson` code for `notes`.
None of the provided `TypeHelper` instances support the defined type.
package:hx_tech_app/domain/models.dart:28:25
   ╷
28 │   final BuiltList<Note> notes;
   │                         ^^^^^
   ╵

Is there a different way I should approach this? Perhaps a TypeHelper?

I have been looking online for documentation for adding TypeHelper but I can't find any anywhere and the example in this repo does not add TypeHelpers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions