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.
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.
import 'dart:convert';
class Job {
String type;
int salary;
String company;
Job(this.type, this.salary, this.company);
String toJson() { var jsm = new Map<String, Object>(); jsm["type"] = type; jsm["salary"] = salary; jsm["company"] = company; var jss = JSON.encode(jsm); return jss; }
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.
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:
Part of the work is done by functions in the imported dart:convert
library, which produces and consumes JSON data, respectively:
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:
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" } ';
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/.