dart-flutter-parse-json-string-array-to-object-list-feature-image

Dart/Flutter – Convert/Parse JSON string, array into Object, List

In this Dart/Flutter tutorial, we’re gonna look at ways to convert/parse JSON string into Object, Nested Object, how to parse JSON array, array of JSON objects into List. Finally, you can parse complex JSON into Nested Object (that also contains array as a field).


Overview

dart:convert library has a built-in jsonDecode top-level function that can parse a string and return the a JSON object (dynamic).

We have 3 steps to convert/parse JSON into Dart Object, Array:

  • get JSON object from string using jsonDecode() function
  • create class that has fields corresponding to key/value pairs of the JSON
  • assign each JSON object value to the fields of the class instance (we will do this in factory .fromJson() method)

For every type of Object, Nested Object, simple Array, Array of Objects, or Nested Object containing Array, we will implement the parser with some little difference.

Now, let’s go to the next sections.

Dart/Flutter parse JSON string into Object

Assume that we have a simple JSON structure like this:

{
  "name": "bezkoder",
  "age": 30
}

We will create a Dart class named User with fields: name & age.

class User {
  String name;
  int age;

  User(this.name, this.age);

  factory User.fromJson(dynamic json) {
    return User(json['name'] as String, json['age'] as int);
  }

  @override
  String toString() {
    return '{ ${this.name}, ${this.age} }';
  }
}

You can see factory User.fromJson() method in the code above. It parses a dynamic object into User object. So how to get dynamic object from a JSON string?

We use dart:convert library’s built-in jsonDecode() function.

import 'dart:convert';

main() {
  String objText = '{"name": "bezkoder", "age": 30}';

  User user = User.fromJson(jsonDecode(objText));

  print(user);

The result will look like this.

{ bezkoder, 30 }

Dart/Flutter parse JSON string into Nested Object

With the JSON string as a nested object like this.

{
  "title": "Dart Tutorial",
  "description": "Way to parse Json",
  "author": {
    "name": "bezkoder",
    "age": 30
  }
}

There are 2 classes we can think about:

  • User for author
  • Tutorial for {title, description, author}

So we can define a new Tutorial like this.

class User {
  String name;
  int age;
  ...
}

class Tutorial {
  String title;
  String description;
  User author;

  Tutorial(this.title, this.description, this.author);

  factory Tutorial.fromJson(dynamic json) {
    return Tutorial(json['title'] as String, json['description'] as String, User.fromJson(json['author']));
  }

  @override
  String toString() {
    return '{ ${this.title}, ${this.description}, ${this.author} }';
  }
}

The main() function now looks like the following code.

import 'dart:convert';

main() {
  String nestedObjText =
      '{"title": "Dart Tutorial", "description": "Way to parse Json", "author": {"name": "bezkoder", "age": 30}}';

  Tutorial tutorial = Tutorial.fromJson(jsonDecode(nestedObjText));

  print(tutorial);

Check the result, you can see our nested object:

{ Dart Tutorial, Way to parse Json, { bezkoder, 30 } }

Dart/Flutter parse JSON array into List

With simple array like the following:

{
  "tags": [
    "dart",
    "flutter",
    "json"
  ]
}

We can easily parse the JSON into a Dart array without the need of creating any class.

import 'dart:convert';

main() {
  String arrayText = '{"tags": ["dart", "flutter", "json"]}';

  var tagsJson = jsonDecode(arrayText)['tags'];
  List tags = tagsJson != null ? List.from(tagsJson) : null;

  print(tags);
}

Now you can see the result of printing the Dart Array.

[dart, flutter, json]

Dart/Flutter parse array of JSON objects into List

How about more complicated JSON array? For example, every item in the array is a JSON object.

{
  "tags": [
    {
      "name": "dart",
      "quantity": 12
    },
    {
      "name": "flutter",
      "quantity": 25
    },
    {
      "name": "json",
      "quantity": 8
    }
  ]
}

We will need a class that represents the Tag item. So we create Tag class with 2 fields like this.

class Tag {
  String name;
  int quantity;

  Tag(this.name, this.quantity);

  factory Tag.fromJson(dynamic json) {
    return Tag(json['name'] as String, json['quantity'] as int);
  }

  @override
  String toString() {
    return '{ ${this.name}, ${this.quantity} }';
  }
}

The method factory Tag.fromJson(dynamic json) will parse a dynamic object into a Tag object. We will need it in the main() function, at the mapping step.

import 'dart:convert';

main() {
  String arrayObjsText =
      '{"tags": [{"name": "dart", "quantity": 12}, {"name": "flutter", "quantity": 25}, {"name": "json", "quantity": 8}]}';

  var tagObjsJson = jsonDecode(arrayObjsText)['tags'] as List;
  List tagObjs = tagObjsJson.map((tagJson) => Tag.fromJson(tagJson)).toList();

  print(tagObjs);
}

Let me explain the code above. It’s simple.
jsonDecode() convert the 'tags' JSON object into a dynamic object. Then we use brackets ['tags'] to get JSON array inside it.
as List returns a List<dynamic> that we will use map() to change every dynamic item of the List into Tag object.
– Finally, .toList() convert the Iterable result above into List<Tag> object.

Now, if we run the code, the result will be like this.

[{ dart, 12 }, { flutter, 25 }, { json, 8 }]

Dart/Flutter parse complex JSON into Nested Object

Welcome to the last section of this tutorial.
We will parse a complex JSON that contains some fields and an array of objects field. It looks like this:

{
  "title": "Dart Tutorial",
  "description": "Way to parse Json",
  "author": {
    "name": "bezkoder",
    "age": 30
  },
  "tags": [
    {
      "name": "dart",
      "quantity": 12
    },
    {
      "name": "flutter",
      "quantity": 25
    }
  ]
}

We modify the Tutorial class to make it have a new List<Tag> tags field.

class Tutorial {
  String title;
  String description;
  User author;
  List tags;

  Tutorial(this.title, this.description, this.author, [this.tags]);

  factory Tutorial.fromJson(dynamic json) {
    if (json['tags'] != null) {
      var tagObjsJson = json['tags'] as List;
      List _tags = tagObjsJson.map((tagJson) => Tag.fromJson(tagJson)).toList();

      return Tutorial(
        json['title'] as String,
        json['description'] as String,
        User.fromJson(json['author']),
        _tags
      );
    } else {
      return Tutorial(
        json['title'] as String,
        json['description'] as String,
        User.fromJson(json['author'])
      );
    }
  }

  @override
  String toString() {
    return '{ ${this.title}, ${this.description}, ${this.author}, ${this.tags} }';
  }
}

– In the constructor method, we use square brackets [this.tags] to specify that this tags array is an option field.
– Like the way we parse array of JSON objects into a Dart List, we use map() and toList() to get List<Tag>.

List _tags = tagObjsJson.map((tagJson) => Tag.fromJson(tagJson)).toList();

The main() function now look like this.

import 'dart:convert';

main() {
  String complexText =
      '{"title": "Dart Tutorial", "description": "Way to parse Json", "author": {"name": "bezkoder", "age": 30}, "tags": [{"name": "dart", "quantity": 12}, {"name": "flutter", "quantity": 25}]}';

  Tutorial complexTutorial = Tutorial.fromJson(jsonDecode(complexText));

  print(complexTutorial);
}

You can see the result with title, description, author, tags array after running the code above.

{ Dart Tutorial, Way to parse Json, { bezkoder, 30 }, [{ dart, 12 }, { flutter, 25 }] }

Conclusion

Today we have learned way to convert or parse many kind of JSON string into a Dart/Flutter Object, Array (List).

One of the most important part that makes our parsing process simple is the dart:convert library’s built-in jsonDecode() function. You also see the way we define Dart class with factory method to convert a input dynamic object into the class instance.

Happy Learning! See you again.

Further Reading

Leave a Reply

Your email address will not be published. Required fields are marked *