Photo by Markus Spiske on Unsplash

Serializing Your Object In Flutter

If you intend to save user data to the shared preferences or local storage in your Flutter application, you will need to serialize it manually. This is because both methods only support a limited selection of primitive object types and your object will probably not fall into any category. To do this we will be using the dart:convert decoder with its jsonEncode/jsonDecode methods, so make sure to import it into your project.

To do this, import the class in your main dart file:

It all starts with a model

To allow our object to become enabled for decoding/encoding we first need to create a Model class for it. This class will represent the object and it’s fields and have the important methods which will do the heavy work of encoding/decoding. The first one is called fromJson and the second one is called toJson. We will show various examples of complex objects and how to serialize them, but for the beginning, we’ll start with a simple one.

We’ll imagine we have a doughnut shop, where we have various doughnuts. Each doughnut is an object that contains the following keys:

  • Name - String
  • Filling - String
  • Topping - String
  • Price - Double

In Dart, it would like this:

doughnut.dart

You may have noticed a weird type in there called dynamic. Dynamic signifies an unknown type in the dart language, one which will be realized during runtime. Think of it as similar to the Object type in Java, which all types inherit from. Any object can be cast into dynamic to invoke methods on it. If no type is declared for a variable or a return type for a method, it is assumed to be dynamic.


Photo by Patrick Fore on Unsplash

Serialize it

Now that we have our model class, we can use it to serialized and de-serialize our data. Below is an example of just how to do that.

Creating a doughnut object is simple:

And now we can serialize it by using jsonEncode:

Under the hood, jsonEncode calls our own toJson method that we created in our doughnut model class. The same also applies for jsonDecode as it calls the fromJson method.

In string form, our doughnut object, now looks like this:

And after we decode it,

we will get:

Did you notice the subtle differences?

The decoded object is now a Map with keys of string type and values of dynamic type. If we want to convert this data type back to our original object, we need to access the properties of the map:

We can access the properties that once belonged to our object by bracket notation

Arrays

Life is not as simple as a doughnut(if only, right?), so we have to take into account that we won’t always be dealing with parameter types that are simple. Let’s assume that the toppings field is not a String, but is an Array of strings. First, let’s redefine the toppings field:

Then, in our fromJson method we will have to do the following:

Notice, how we have a temporary variable to first extract the value from the json variable and then we explicitly convert the value to our toppings list original type. We have to do this since at first, the type for the value of toppings is dynamic and dart does not know which type it is explicitly.


Photo by sheri silver on Unsplash

Complex Objects

No one ever buys only one doughnut, right? That would be useless. Let’s imagine we have a dozen. So now we are dealing with a list of objects of Doughnut type. To serialize/de-serialize a list of objects we will use the model class above, but we will need to create a different model class to handle the list.

DoughnutList Model Class

As you can see, we now have a model class that has a field of type List that holds Doughnut objects.

Similar to the example above, to serialize the object we use the jsonEncode method and when we want to decode the object we have to perform the following:

Notice how we iterate over the decoded list to decode every Doughnut object in it