JSON is one of the most commonly used data formats in Flutter development. In this article, we mainly look at the parsing of JSON data in Flutter in several of the most common formats in Flutter development:

In each of the following cases, we put the JSON files locally, namely assets files, and then read the files locally for parsing.

If we need to read assets/person.json:

The following configuration is required in pubspec.yaml:

flutter:
	uses-material-design:  true
	Resource file configuration
	assets:
		-  assets/person.json
Copy the code

Let’s take a look at some common Json formatted data.

If you’re not familiar with the basics of Dart, check out this article: Introduction to Dart Basics

Simple object parsing

Define a person.json as follows:

{
	"name":  "jack"."age":  18."height":  175.0
}
Copy the code

As in Java, we first need to build a Person entity class like this:

class Person {
  String name;
  int age;
  double height;

  Person({this.name, this.age, this.height});

  factory Person.fromJson(Map<String.dynamic> json) {
    return Person(name: json['name'], age: json['age'], height: json['height']); }}Copy the code

Next, we create a person_service.dart to parse Person.json.

The following dependency libraries need to be imported into this class:

// Use the rootBundle object in the library to read the perosn.json file
import 'package:flutter/services.dart';  
// json
import 'dart:convert';  
Asynchronous Future / /
import 'dart:async';
Copy the code

person_service.dart

import 'package:flutter/services.dart';
import 'dart:convert';
import 'dart:async';
import '.. /models/person.dart';

// Read the Person. json file in assets
Future<String> _loadPersonJson() async {
  return await rootBundle.loadString('assets/person.json');
}

// Parse the JSON string into a Person object
Future<Person> decodePerson() async {
  // Get the local JSON string
  String personJson = await _loadPersonJson();

  // Parse json String, return Map
      
        type
      ,>
  final jsonMap = json.decode(personJson);

  print('jsonMap runType is ${jsonMap.runtimeType}');

  Person person = Person.fromJson(jsonMap);

  print(
      'person name is ${person.name}, age is ${person.age}, height is ${person.height}');

  return person;
}
Copy the code

Enter the following:

flutter: jsonMap runType is _InternalLinkedHashMap<String.dynamic>
flutter: person name is jack, age is 18, height is 175.0
Copy the code

The json.decode(personJson) method returns _InternalLinkedHashMap

. For example, in person.json, keys are strings, but values can be strings, ints, doubles, etc.
,>

An object that contains an array

Define a country. Json as follows:

{
    "name": "China"."cities": [
        "Beijing"."Shanghai"]}Copy the code

The entity class is as follows:

class Country {  
  String name;  
  List<String> cities;  
  
  Country({this.name, this.cities});  
  
  factory Country.fromJson(Map<String.dynamic> json) {  
  return Country(name: json['name'], cities: json['cities']); }}Copy the code

The Service class is as follows:

import 'dart:async';
import 'package:flutter/services.dart';
import 'dart:convert';
import '.. /models/country.dart';

Future<String> _loadCountryJson() async {
  return await rootBundle.loadString('assets/country.json');
}

Future<Country> decodeCountry() async {
  String countryJson = await _loadCountryJson();

  Map<String.dynamic> jsonMap = json.decode(countryJson);

  Country country = Country.fromJson(jsonMap);
  print('country name is ${country.name}');
  return country;
}
Copy the code

Then we call decodeCountry() in main(), error…

Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<String>'
...
Copy the code

The error log says that List

is not a subtype of List

, so we assign cities directly to cities in the country entity class: Json [‘cities’] json[‘cities’]

factory Country.fromJson(Map<String.dynamic> json) {  
  print('json["cities"] type is ${json['cities'].runtimeType}');  
  return Country(name: json['name'], cities: json['cities']);  
}
Copy the code

The output is as follows:

flutter: json["cities"] type is List<dynamic>
Copy the code

At this point we need to put country.fromjson (…) The method is changed as follows:

factory Country.fromJson(Map<String.dynamic> json) {
    print('json["cities"] type is ${json['cities'].runtimeType}');
    var originList = json['cities'];
    List<String> cityList = new List<String>.from(originList);
    return Country(name: json['name'], cities: cityList);
  }
Copy the code

In the code above, we create an array of type List

and add all the elements from the List< Dynamic > array to List

. The output is as follows:

flutter: json["cities"] type is List<dynamic>
flutter: country name is China
Copy the code

Nested object

Define a shape.json file in the following format:

{  
  "name": "rectangle"."property": {  
  "width": 5.0."height": 10.0}}Copy the code

The entities are as follows:

class Shape {  
  String name;  
  Property property;  
  
  Shape({this.name, this.property});  
  
  factory Shape.fromJson(Map<String.dynamic> json) {  
  return Shape(name: json['name'], property: json['property']); }}class Property {  
  double width;  
  double height;  
  
  Property({this.width, this.height});  
  
  factory Property.fromJson(Map<String.dynamic> json) {  
  return Property(width: json['width'], height: json['height']); }}Copy the code

The Service class is as follows:

import 'dart:async';  
import 'dart:convert';  
import 'package:flutter/services.dart';  
import '.. /models/shape.dart';  
  
Future<String> _loadShapeJson() async {  
  return await rootBundle.loadString('assets/shape.json');  
}  
  
Future<Shape> decodeShape() async {  
  String shapeJson = await _loadShapeJson();  
  
  Map<String.dynamic> jsonMap = json.decode(shapeJson);  
  
  Shape shape = Shape.fromJson(jsonMap);  
  
  print('shape name is ${shape.name}');  
  return shape;  
}
Copy the code

After running, the following error is reported:

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Property'
Copy the code

Property: Json [‘property’] = _InternalLinkedHashMap

instead of property {width: 5.0, height: 10.0}, it is a Map, not a Property object, we need to convert the Map to an object, and then assign:
,>

factory Shape.fromJson(Map<String.dynamic> json) {  
  print('json["property"] is ${json['property']}');  
  Property property = Property.fromJson(json['property']);   // new line
  return Shape(name: json['name'], property: property);  
}
Copy the code

Output:

shape name is rectangle
Copy the code

Complex object array nesting

{
  "id": "0302"."class_name": "Class two, Three"."students": [{"name": "Ye Xianglun"."sex": "Male"
    },
    {
      "name": "Road light Rain"."sex": "Female"}}]Copy the code

Entity:

class ClassInfo {
  String id;
  String name;
  List<Student> studentList;

  ClassInfo({this.id, this.name, this.studentList});

  factory ClassInfo.fromJson(Map<String.dynamic> json) {
    return ClassInfo(
        id: json['id'],
        name: json['class_name'],
        studentList: json['students']); }}class Student {
  String name;
  String sex;

  Student({this.name, this.sex});

  factory Student.fromJson(Map<String.dynamic> json) {
    return Student(name: json['name'], sex: json['sex']); }}Copy the code

service:

import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
import '.. /models/class_info.dart';

Future<String> _loadClassInfoJson() async {
  return await rootBundle.loadString('assets/class_info.json');
}

Future<ClassInfo> decodeClassInfo() async {
  String classInfoJson = await _loadClassInfoJson();

  Map<String.dynamic> jsonMap = json.decode(classInfoJson);

  ClassInfo classInfo = ClassInfo.fromJson(jsonMap);
  classInfo.studentList
      .forEach((student) => print('student name is ${student.name}'));
  return classInfo;
}
Copy the code

The above code will still report an error after running:

Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<Student>'
Copy the code

StudentList: json[‘students’] / studentList: json[‘students’] / studentList: json[‘students’] / studentList: json[‘students’] / studentList: json[‘students’] / studentList: json[‘students’]

[{name: Ye Xianglun, sex: male}, {name: Lu Xiaoyu, sex: female}]Copy the code

The above result is of type List

. Now we need to convert List

to an array of type List

using the map operator, which converts one type to another. As follows:


factory ClassInfo.fromJson(Map<String.dynamic> json) {  
  final originList = json['students'] as List;  
  List<Student> studentList =  
      originList.map((value) => Student.fromJson(value)).toList();  
  return ClassInfo(  
  id: json['id'], name: json['class_name'], studentList: studentList);  
}
Copy the code

Output:

The student name of the flutter is light rainCopy the code

Pure array

member.json

[{"id": 1."name": "Jack"
  },
  {
    "id": 2."name": "Rose"
  },
  {
    "id": 3."name": "Karl"}]Copy the code

Entity:

class MemberList {  
  List<Member> memberList;  
  
  MemberList({this.memberList});  
  
  factory MemberList.fromJson(List<dynamic> listJson) {  
  
  List<Member> memberList =  
        listJson.map((value) => Member.fromJson(value)).toList();  
  
  returnMemberList(memberList: memberList); }}class Member {  
  int id;  
  String name;  
  
  Member({this.id, this.name});  
  
  factory Member.fromJson(Map<String.dynamic> json) {  
  return Member(id: json['id'], name: json['name']); }}Copy the code

Json is a pure array, so in the code above we create a MemberList class to contain this member array.

Note in the above code memberList.fromjson (…) Is written in.

service:

import 'dart:async';
import 'package:flutter/services.dart';
import 'dart:convert';
import '.. /models/member.dart';

Future<String> _loadMemberJson() async {
  return await rootBundle.loadString('assets/member.json');
}

Future<MemberList> decodeMemberList() async {
  String memberListJson = await _loadMemberJson();

  List<dynamic> list = json.decode(memberListJson);

  MemberList memberList = MemberList.fromJson(list);

  memberList.memberList
      .forEach((member) => print('member name is ${member.name}'));

  return memberList;
}
Copy the code

Output:

flutter: member name is Jack
flutter: member name is Rose
flutter: member name is Karl
Copy the code

Complex Json parsing

In my previous article, the ListView of Flutter uses the Douban API. The data returned by this API contains the current hot movies, so try parsing them on demand!!

Please point out any mistakes. Thanks!!

The source address

Reference links:

Medium.com/flutter-com…

Github.com/flutter/flu…