# JSON
# Overview
ezFlap offers the @EzJson annotation to allow easy serialization of data classes into JSON, and deserialization from
JSON.
The ezFlap JSON serializer/deserializer has the following features:
- Serialize primitives:
int,num,double, andString. - Serialize collections of primitives:
List<int>,Set<num>,Map<String, String>, etc. - Serialize reactive collections:
RxList<String>,RxMap<String, double>, etc. - Serialize collections of collections of primitives:
List<Set<num>>,Map<String, Map<String, double>>, etc. - Serialize collections of collections of collections of primitives (and so on, to infinity).
- Serialize referenced instances of
@EzJsondata classes. - Serialize collections of instances of
@EzJsondata classes (recursively). - Serialize into a
Map<String, dynamic>(which can be passed to json.encode (opens new window)). - Serialize into a String (as JSON).
- Deserialize (all of the above).
- Works well with
@EzReactiveto make data classes both serializable and reactive.
# @EzJson
We use the @EzJson annotation to add JSON support to a class.
We use the @EzValue annotation to add JSON support to a field in the class.
# Example

The above example shows how to use @EzJson and @EzValue.
Additionally:
- Our data class (
JsonAnimal) extends the generated_JsonAnimalBaseclass.- The name
_JsonAnimalBaseis created automatically according to the name of our class (i.e. JsonAnimal).
- The name
- A couple of fields are
lateand one is nullable. Both variations are supported.- Default values are not currently supported.
# Serialization
# Simple class
This is how a JsonAnimal instance can be serialized:

In the above example, we instantiate JsonAnimal with JsonAnimal() and then populate it using the
_JsonAnimalBase.from() method.
This method is generated automatically, and has a named parameter for each @EzValue field.
The output of the above example is:
{"id":42,"name":"cat","iq":126.7,"previousOwnersList":["Alice","Bob"]}
# Recursive Classes
Let's create a JsonOwner class:

The JsonOwner class contains JsonAnimal instances in a couple of fields:
favoriteAnimal- holds a single instance.otherAnimalsByIdsMap- holds multipleJsonAnimalinstances with theiridas the key.
Let's serialize it:

The output of the above example is:
{"id":42,"name":"Alice","favoriteAnimal":{"id":37,"name":"cat","iq":126.7},"otherAnimalsByIdsMap":{"55":{"id":55,"name":"dog","iq":126.699},"3112":{"id":3112,"name":"tardigrade","iq":3.0}}}
ONLY STRING KEYS IN MAPS
Serializable Maps must have keys of type String.
# Deep Collections
Let's see what happens when we use a deep hierarchy of collections:

And then serialize:

The output of the above example is:
{"deepMap":{"itemA1":[[{"itemB1":{"itemC1":{"itemD1":{"itemE1":42,"itemE2":17,"itemE3":88},"itemD2":{"itemE1":142,"itemE2":117,"itemE3":188}},"itemC2":{"itemD1":{"itemE1":242,"itemE2":217,"itemE3":288},"itemD2":{"itemE1":342,"itemE2":317,"itemE3":388}}}}]],"itemA2":[[{"itemB1":{"itemC1":{"itemD1":{"itemE1":442,"itemE2":417,"itemE3":488},"itemD2":{"itemE1":542,"itemE2":517,"itemE3":588}},"itemC2":{"itemD1":{"itemE1":642,"itemE2":617,"itemE3":688},"itemD2":{"itemE1":742,"itemE2":717,"itemE3":788}}}}]]}}
# Serialization to Map
An @EzJson class can also be serialized into a map.
Instead of using toJson() - use toJsonMap():

The output of the above example is:
Map: {id: 42, name: cat, iq: 126.7}
# Deserialization
There are four ways to deserialize data into an @EzJson class:
- As a new instance, with a static factory:
- From JSON.
- From
Map<String, dynamic>.
- Into an existing instance, using a member method:
- From JSON.
- From
Map<String, dynamic>.
# With Static Factories
The generated code contains two static factories that can be used to instantiate and then populate an @EzJson class
from JSON and from a Map:
factoryFromJson.factoryFromJsonMap.
Dart does not support static method inheritance, so we "re-define" these methods in our own data class, and delegate the actual logic to corresponding generated methods in the generated parent class.
# Example

This is how a JsonAnimalWithFactories instance can be instantiated from JSON:

This is how a JsonAnimalWithFactories instance can be instantiated from Map<String, dynamic>:

# With Member Methods
We can also populate an existing instance of an @EzJson class using its fromJson() and fromJsonMap() functions.
# Example

# Making Classes Reactive
@EzJson classes support reactive collections:

CAVEAT
Rx wrappers around primitives are not supported.
# With @EzReactive
To make primitives and other data classes reactive - use @EzReactive:

In the above example, the @EzReactive annotation is added underneath @EzJson, and we can see that the names of the
fields are now in the _$<name> format.
Non-reactive @EzJson classes support "natural" field names.
When adding @EzReactive - we need to use the "pseudo" field names.
Like with non-JSON reactive data classes - the fields are accessed using their "natural" names (e.g.
JsonOwnerRx._$name is accessed as JsonOwnerRx.name).
BUT WHY?
The reason for this difference is that the fields in @EzReactive classes need to be replaced with getter/setter
properties (which are created in the generated code).
However, the code generated for non-reactive @EzJson data classes does not need such properties, and therefore can
work with "actual" fields directly.
← Routing Core Widgets →