ZetCode

Dart JSON

last modified January 28, 2024

In this article we show how to work with JSON in Dart language. We use the dart:convert library.

JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easily read and written by humans and parsed and generated by machines. The application/json is the official Internet media type for JSON. The JSON filename extension is .json.

Dart also has JSON generation libraries package:json_serializable and package:built_value. In this article we focus on the built-in dart:convert library.

For each class that is going to be converted to/from JSON, we define two methods: fromJson and toJson.

The fromJson is used for constructing a new object instance from a map structure. The toJson method converts a class instance into a map. These functions are used in conjunction with the dart:convert's json.decode and json.encode.

The json.decode function parses the JSON string and returns the resulting Json object (a Dart map). The json.encode function converts an object to a JSON string.

Dart JSON simple example

The following is a simple Dart example that works with JSON data.

main.dart
import 'dart:convert';

class User {
  final String name;
  final String occupation;

  User(this.name, this.occupation);

  User.fromJson(Map<String, dynamic> m)
      : name = m['name'],
        occupation = m['occupation'];

  Map<String, dynamic> toJson() => {
        'name': name,
        'occupation': occupation,
      };

  @override
  String toString() {
    return "$name|$occupation";
  }
}

void main() {
  final u1Json = '{"name": "John Doe", "occupation": "gardener"}';
  final u1 = User.fromJson(json.decode(u1Json));

  print(u1);

  final u2 = User('Roger Roe', 'gardener');
  final u2Json = json.encode(u2);

  print(u2Json);
}

In the program, we convert a JSON string to a Dart object and vice versa.

import 'dart:convert';

We import the dart:convert library.

User.fromJson(Map<String, dynamic> m)
    : name = m['name'],
      occupation = m['occupation'];

This creates a new User instance from the map structure.

Map<String, dynamic> toJson() => {
  'name': name,
  'occupation': occupation,
};

The toJson method creates a map structure from an object instance.

final u1Json = '{"name": "John Doe", "occupation": "gardener"}';

We define a JSON string.

final u1 = User.fromJson(json.decode(u1Json));

We use json.decode to convert the string to a map and pass it to the User.fromJson method to create a User object from the generated map.

final u2 = User('Roger Roe', 'gardener');
final u2Json = json.encode(u2);

Now we have the reverse operation. We define a User object and transform it into a JSON string using json.encode.

$ dart main.dart
John Doe|gardener
{"name":"Roger Roe","occupation":"gardener"}

We also have jsonDecode and jsonEncode shorthand functions, which are useful if a local variable shadows the global json constant.

main.dart
import 'dart:convert';

class User {
  final String name;
  final String occupation;

  User(this.name, this.occupation);

  User.fromJson(Map<String, dynamic> m)
      : name = m['name'],
        occupation = m['occupation'];

  Map<String, dynamic> toJson() => {
        'name': name,
        'occupation': occupation,
      };

  @override
  String toString() {
    return "$name|$occupation";
  }
}

void main() {
  final u1Json = '{"name": "John Doe", "occupation": "gardener"}';
  final u1 = User.fromJson(jsonDecode(u1Json));

  print(u1);

  final u2 = User('Roger Roe', 'gardener');
  final u2Json = jsonEncode(u2);

  print(u2Json);
}

In the program we do the same convertions with jsonDecode and jsonEncode.

Dart list of Json objects

In the next example, we convert a list of Json objects into a JSON string.

main.dart
import 'dart:convert';

void main() {
  final users = [
    {'name': 'John Doe', 'occupation': 'gardener'},
    {'name': 'Roger Roe', 'occupation': 'driver'},
    {'name': 'Thomas Brown', 'occupation': 'teacher'}
  ];

  final res = json.encode(users);
  print(res);
}

We have a list of users. Each user is defined by a Map<String, String>. We convert the list into a JSON string with json.encode.

$ dart main.dart
[{"name":"John Doe","occupation":"gardener"},{"name":"Roger Roe","occupation":"driver"},
 {"name":"Thomas Brown","occupation":"teacher"}]

Dart list of objects

In the next example, we work with a list of User objects.

main.dart
import 'dart:convert';

class User {
  final String name;
  final String occupation;

  User(this.name, this.occupation);
  User.fromJson(Map<String, dynamic> m)
      : name = m['name'],
        occupation = m['occupation'];

  Map<String, dynamic> toJson() => {
        'name': name,
        'occupation': occupation,
      };

  @override
  String toString() {
    return "$name|$occupation";
  }
}

void main() {
  final users = <User>[
    User("John Doe", "gardener"),
    User("Roger Roe", "driver"),
    User("Finn Bradley", "teacher")
  ];

  String res = json.encode(users);
  print(res);

  print('----------------------------------');

  List<dynamic> data = json.decode(res);
  List<User> users2 =
      List<User>.from(data.map<User>((dynamic e) => User.fromJson(e)));

  print(users2);
}

We convert a list of users into a JSON string and vice versa.

final users = <User>[
  User("John Doe", "gardener"),
  User("Roger Roe", "driver"),
  User("Finn Bradley", "teacher")
];

We define a list of user objects.

String res = json.encode(users);

The list is encoded into a JSON string with json.encode.

List<dynamic> data = json.decode(res);

We decode the JSON string into a list.

List<User> users2 =
  List<User>.from(data.map<User>((dynamic e) => User.fromJson(e)));

The list is transformed into a list of User instances.

$ dart main.dart 
[{"name":"John Doe","occupation":"gardener"},{"name":"Roger Roe","occupation":"driver"},
 {"name":"Finn Bradley","occupation":"teacher"}]
----------------------------------
[John Doe|gardener, Roger Roe|driver, Finn Bradley|teacher]

Dart fetch JSON data from URL

In the next example, we fetch JSON data from an URL resource.

main.dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class User {
  final int id;
  final String firstName;
  final String lastName;
  final String email;

  User(this.id, this.firstName, this.lastName, this.email);
  User.fromJson(Map<String, dynamic> m)
      : id = m['id'],
        firstName = m['first_name'],
        lastName = m['last_name'],
        email = m['email'];

  Map<String, dynamic> toJson() => {
        'id': id,
        'first_name': firstName,
        'last_name': lastName,
        'email': email,
      };

  @override
  String toString() {
    return "$id|$firstName|$lastName|$email";
  }
}

void main() async {
  final url = 'webcode.me';
  final path = '/users.json';

  final resp = await http.get(Uri.http(url, path));
  List<dynamic> data = json.decode(resp.body)['users'];

  List<User> users =
      List<User>.from(data.map<User>((dynamic e) => User.fromJson(e)));

  print(users);
  print(users[0]);
  print(json.encode(users[0]));
}

In the example, we generate a GET request to a web resource. The resource is in JSON format.

class User {
  final int id;
  final String firstName;
  final String lastName;
  final String email;

  User(this.id, this.firstName, this.lastName, this.email);
  User.fromJson(Map<String, dynamic> m)
      : id = m['id'],
        firstName = m['first_name'],
        lastName = m['last_name'],
        email = m['email'];

  Map<String, dynamic> toJson() => {
        'id': id,
        'first_name': firstName,
        'last_name': lastName,
        'email': email,
      };

  @override
  String toString() {
    return "$id|$firstName|$lastName|$email";
  }
}

We have a User class. The JSON resource has the following fields: id, first_name, last_name, and email. We define the User.fromJson and toJson methods.

final url = 'webcode.me';
final path = '/users.json';

final resp = await http.get(Uri.http(url, path));

We generate a GET request to the specified resource.

List<dynamic> data = json.decode(resp.body)['users'];

We decode the JSON resource into a list. The resource is a named list; therefore, we pick the users field.

List<User> users =
  List<User>.from(data.map<User>((dynamic e) => User.fromJson(e)));

The list is transformed into a list of User objects.

$ dart main.dart
[1|Robert|Schwartz|[email protected], 2|Lucy|Ballmer|[email protected], 
  3|Anna|Smith|[email protected], 4|Robert|Brown|[email protected], 
  5|Roger|Bacon|[email protected]]
1|Robert|Schwartz|[email protected]
{"id":1,"first_name":"Robert","last_name":"Schwartz","email":"[email protected]"}

Source

Dart Using JSON Guide

In this article we have worked with JSON data in Dart. We utilized the dart:convert library.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Dart tutorials.