Serializable class Null safety

This is the base class for all JSON serializable objects.

Using this class allow for implementing both serialization and deserialization to/from JSON. This is done using the json_serializable package.

It also allows for serialization of polymorphic classes.

To support polymorphic serialization, each subclass should:

  • annotate the class with @JsonSerializable
  • add the three json methods
    • Function get fromJsonFunction => ...
    • factory ...fromJson(...)
    • Map<String, dynamic> toJson() => ...
  • register the classes in the FromJsonFactory() registry.
  • build json function using the flutter pub run build_runner build --delete-conflicting-outputs command

Below is a simple example of two classes A and B where B extends A.

@JsonSerializable(fieldRename: FieldRename.none, includeIfNull: false)
class A extends Serializable {
  int index;

  A() : super();

  Function get fromJsonFunction => _$AFromJson;
  factory A.fromJson(Map<String, dynamic> json) =>
      FromJsonFactory().fromJson(json) as A;
  Map<String, dynamic> toJson() => _$AToJson(this);
}

@JsonSerializable(fieldRename: FieldRename.none, includeIfNull: false)
class B extends A {
  String str;

  B() : super();

  Function get fromJsonFunction => _$BFromJson;
  factory B.fromJson(Map<String, dynamic> json) =>
      FromJsonFactory().fromJson(json) as B;
  Map<String, dynamic> toJson() => _$BToJson(this);
}

Note that the naming of the fromJson() and toJson() functions follows json_serializable package. For example the fromJson function for class A is called _$AFromJson.

The fromJsonFunction must be registered on app startup (before use of de-serialization) in the FromJsonFactory singleton, like this:

 FromJsonFactory().register(A());

For this purpose it is helpful to have an empty constructor, but any constructur will work, since only the fromJsonFunction function is used. Hence, a private constructure like A._() is also fine.

Polymorphic serialization is handled by setting the $type property in the Serializable class. Per default, an object's runtimeType is used as the $type for an object. Hence, the json of object of type A and B would look like this:

 {
  "$type": "A",
  "index": 1
 }
 {
  "$type": "B",
  "str": "abc"
 }

However, if you want to specify your own object/class type (e.g., if you get json serialized from another language which uses a package structure like Java, C# or Kotlin), you can specify the json type in the jsonType property of the class.

For example, if the class B above should use a different $type annotation, using the following:

@JsonSerializable(fieldRename: FieldRename.none, includeIfNull: false)
class B extends A {

  <<as above>>

  String get jsonType => 'dk.cachet.$runtimeType';
}

In which case the json would look like:

 {
  "$type": "dk.cachet.B",
  "str": "abc"
 }
Implementers

Constructors

Serializable()
Create an object that can be serialized to JSON.

Properties

$type String?
The runtime class name (type) of this object. Used for deserialization from JSON objects.
read / write
fromJsonFunction Function
The function which can convert a JSON string to an object of this type.
read-only
hashCode int
The hash code for this object. [...]
read-only, inherited
jsonType String
Return the $type to be used for JSON serialization of this class. Default is runtimeType. Only specify this if you need another type.
read-only
runtimeType Type
A representation of the runtime type of the object.
read-only, inherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
inherited
toJson() Map<String, dynamic>
Return a JSON encoding of this object.
toString() String
A string representation of this object. [...]
inherited

Operators

operator ==(Object other) bool
The equality operator. [...]
inherited

Constants

CLASS_IDENTIFIER → const String
The identifier of the class type in JSON serialization.
'\$type'