Flutter/Dart - Convert (Serialize) Object to JSON / String

If you're developing a Flutter application (or any application using Dart language) and you need to convert (serialize or stringify) a Dart object to JSON object or string, you come to the right place. In this tutorial, I'm going to show you from example with simple object and then continued with a complex object with nested structure.

Simple Class with Array of Primitive Types

As for example, we have a class Item as the following.

  class Item {
    int id;
    String name;
    List<String> locations;
    double price;
    int stock;
    bool active;
  }

To get the JSON object of an Item instance, you need to implement toJson method which returns Map<String, dynamic>. Inside, for every key you want to present on the JSON object, choose which property of the class you want to use. Here is the implementation of toJson.

  class Item {
    int id;
    String name;
    List<String> locations;
    double price;
    int stock;
    bool active;

    Map<String, dynamic> toJson() => _itemToJson(this);
  }
  Map<String, dynamic> _itemToJson(Item instance) {
    return <String, dynamic>{
      'id': instance.id,
      'name': instance.name,
      'locations': instance.locations,
      'price': instance.price,
      'stock': instance.stock,
      'active': instance.active,
    };
  }

Here's the usage example of toJson(). To get the value of a JSON key, use `[key-name]`, while for converting the JSON to a string, use toString() on the JSON object.

  Item item = new Item(
      id: 1,
      name: 'Item1',
      locations: ['Abcde', '12345'],
      price: 100.00,
      stock: 10,
      active: true,
    );

    Map<String, dynamic> itemJson = item.toJson();
    print(itemJson['name']);
    print(itemJson.toString());

Nested Class

Now the Item class has a new property: dimensions whose type is Dimensions.

  class Dimensions {
    double width;
    double depth;
    double height;

    Dimensions({this.width, this.depth, this.height});
  }

You cannot simply add 'dimensions': instance.dimensions inside toJson(). You need to implement another toJson() method for the Dimensions class.

  class Dimensions {
    double width;
    double depth;
    double height;

    Dimensions({this.width, this.depth, this.height});
    Map<String, dynamic> toJson() => _dimensionsToJson(this);
  }

Map<String, dynamic> _dimensionsToJson(Dimensions instance) => <String, dynamic>{ 'width': instance.width, 'depth': instance.depth, 'height': instance.height, };

Then, modify _itemToJson to use Dimensions' toJson() method. Beforehand, you need to check if the dimensions value is not null.

  Map<String, dynamic> _itemToJson(Item instance) {
    Map<String, dynamic> dimensions = instance.dimensions != null
      ? instance.dimensions.toJson()
      : null;

    return <String, dynamic>{
      // Other properties
      'dimensions': dimensions,
    };
  }

In case the inner class also has another inner class, you need to implement another toJson - do it recursively until you don't find nested class.

Class with Array of Nested Class

Let's say the Item class has a new property purchases whose type is List<Purchase>. How to handle this kind of structure?

First, you have to create toJson method for the Purchase class.

  class Purchase {
    int amount;
    String customerName;
  
    Purchase({this.amount, this.customerName});
    Map<String, dynamic> toJson() => _purchaseToJson(this);
  }
  
  Map<String, dynamic> _purchaseToJson(Purchase instance) => <String, dynamic>{
    'amount': instance.amount,
    'customerName': instance.customerName,
  };

Then, use map on purchases property. For each element, returns the JSON object by using Purchase's toJson method. Then, convert the map result to List<Map<String, dynamic>> by using toList().

  Map<String, dynamic> _itemToJson(Item instance) {
    List<Map<String, dynamic>> purchases = instance.purchases != null
      ? instance.purchases.map((i) => i.toJson()).toList()
      : null;

    return <String, dynamic>{
      // Other properties
      'purhcases': purchases,
    };
  }

That's how to serialize a Dart object to JSON object or string. If you want to convert in the opposite way, you can read our tutorial about how to deserialize JSON string to object in Dart.