Flutter: Dart Immutable Objects JSON Serialization and Deserialization

Marco Muccinelli
ITNEXT
Published in
2 min readJun 12, 2020

--

In a previous article I discussed about freezed and kt_dart, a couple of packages that bring immutable value types to Dart and Flutter. I omitted to cover a free feature exposed by freezed: the integration with json_serialializable.

Installation

First of all, add the dependency to pubspec.yaml file:

Then, edit your immutable object declaration like this:

  • You need to declare another part file with .g.dart suffix.
  • You need to declare a new factory constructor called fromJson and to bind it to a synthesized deserializer provided by freezed generator.

And that’s it! It just works!

If you provide wrong types or you miss some required fields, `fromJson` will raise an exception.

You also get a free toJson method that returns a Map<String, dynamic>.

You can affect JSON model by using json_serializable annotations. For example. you can change field names:

Immutable collections

While json_serializable is able to handle normal List or Dictionary objects, we want to support immutable types provided by kt_dart package. You have two ways to extend this functionality: the former is to write a bunch of custom converters:

I’m pretty sure you have already spotted the problem: since you must call cast() you have to write a converted for each enclosed type. It is not possible to write a generic version at moment. Not a big issue since they one-liners, but a little bit tedious for sure.

The latter way is to use a json_serializable extension called json_serializable_immutable_collections. You install it inside dev_dependencies in pubspec.yaml file:

Then you create a build.yaml file to instruct source generator to use the extension:

Then you can restart build_runner and KtList, KtSet and KtMap will be supported without special converters.

VS Code integration

You could hide the generated files by json_serializable from Explorer tab. To do so, open Settings and search for Files: Exclude preference. Then, you can add this pattern to the list: **/*.g.dart.

--

--