Making toJSON and fromJSON methods in your class

JavaScript Object Notation (JSON) is probably the most widely used data format in web applications, so it is a common requirement for a class to be able to serialize its objects to JSON strings, or reconstruct objects from JSON strings.

Getting ready

JSON is lightweight (not as verbose as XML) and text-based, so it is easily readable by humans. It starts from the notion that the state (or content) of an object is in fact like a map; the keys are the field names, and their values are the concrete data stored in the fields. For example, (see project json/job.dart), say we have a class Job defined, as shown in the following code:

class Job {
  String type;
  int salary;
  String company;
  Job(this.type, this.salary, this.company);
}

Next, we construct a job object with the following code:

var job = new Job("Software Developer", 7500, "Julia Computing  LLC") ;

Then, it can be represented as the following JSON string:

 '{
     "type": "Software Developer",
     "salary": 7500,
     "company": "Julia Computing LLC"
 }'

The values can themselves be lists or maps or lists of maps. For more information about JSON, refer to http://en.wikipedia.org/wiki/JSON.

How to do it...

  • The following is the code to give our class JSON functionality:
    import 'dart:convert';
    
    class Job {
      String type;
      int salary;
      String company;
      Job(this.type, this.salary, this.company);
  • The following is the code to encode or serialize data:
      String toJson() {
        var jsm = new Map<String, Object>();
        jsm["type"] = type;
        jsm["salary"] = salary;
        jsm["company"] = company;
        var jss = JSON.encode(jsm);
        return jss;
      }
  • The following is the code to decode or deserialize data:
      Job.fromJson(String jsonStr) {
        Map jsm = JSON.decode(jsonStr);
        this.type = jsm["type"];
        this.salary = jsm["salary"];
        this.company = jsm["company"];
      }
    }
    void main() {
     var job = new Job("Software Developer", 7500, "Julia Computing LLC") ;
     var jsonStr = job.toJson();
     print(jsonStr);
     var job2 = new Job.fromJson(jsonStr);
     assert(job2 is Job);
     assert(job2.toJson() == jsonStr);
    }

The output of jsonStr is {"type":"Software Developer","salary":7500,"company":"Julia Computing LLC"}.

The assert statements confirm that the decoded object is of type Job and is equal to the JSON string we started from.

How it works...

A JSON string can be stored in a file or database, or sent over the network to a server. So our class needs to be able to:

  • Write its objects out in JSON format, which is also called serializing or encoding; we'll conveniently call this method toJson()
  • Read a JSON string and construct an object (or many objects) from it; this is called deserializing or decoding, and we'll make a method fromJson() to do just this

Part of the work is done by functions in the imported dart:convert library, which produces and consumes JSON data, respectively:

  • JSON.encode(): This serializes a Dart object into a JSON string, ready to be stored or sent over a network
  • JSON.decode(): This builds Dart objects from a string containing JSON data, which is just read from storage or received over the network

These functions on JSON (which is an object of the class JSONCodec) can process data from the types null, num, bool, String, List, and Map automatically and also from a combination of these (the keys of the map need to be strings). In our Job class, the data is processed, as explained in the following points:

  • toJson() makes the map from the object and then calls JSON.encode() on it to return a JSON string
  • fromJson() (conveniently implemented as a named constructor) takes the JSON string, calls JSON.decode() to return a map, and builds the object

There's more...

If your data is not that complicated, you can build the JSON string in the code yourself, possibly as a getter, as shown in the following snippet:

String get toJson => '{"type": "$type", "salary": "$salary", "company": "$company" } ';

Tip

If you have to construct JSON strings literally in your code, make sure to always use double quotes to indicate strings; Dart single quotes cannot be used here.

When an object contains other objects (composition or association, such as a BankAccount object containing a Pe rson object for the owner), the fromJson() and toJson() methods from the outer object will call the corresponding methods with the same name for all the contained objects.

If you want a more sophisticated solution that supports the encoding and decoding of arbitrary objects, look for the jsonx package on pub, by Man Hoang. This library can decode a JSON string into a strongly typed object, which gets type checking and code completion support, or encodes an arbitrary object into a JSON string. When working with JSON, it is preferred to validate it; this can be done online at http://jsonlint.com/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset