简体   繁体   中英

how to parse complex json in flutter

I have trouble getting data from a complex json, below is the json in the request.

{
   "results":{
      "TotalRecordCount":"1",
      "Records":[
         {
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         }
      ],
      "Result":"OK"
   }
}

Below is the model I made.

import 'dart:convert';

class Pickup {
  String status;
  List message;
  //Map<String ,dynamic> results;
  Results results;
  Pickup(
    {this.status,
     this.message,
     this.results,
  });
  factory Pickup.fromJson(Map<String, dynamic> json) {
    return Pickup(
             status: json["status"] as String,
             results: Results.fromJson(json["results"]),

           );
  }
}

class Results {
  String TotalRecordCount;
  records Records;

  Results({this.TotalRecordCount,this.Records});

  factory Results.fromJson(Map<String, dynamic> json) {
    return Results(
    TotalRecordCount: json["TotalRecordCount"],
    Records:records.fromJson(json["Records"]),

    );
  }
}

class records{
  String code;
  String address;
  String contact_phone;

  records({
    this.code,
    this.address,
    this.contact_phone
  });

  factory records.fromJson(Map<String, dynamic> json) {
    return records(
      code: json["code"],
      address: json["address"],
      contact_phone: json["contact_phone"],
    );
  }
}

Now Im trying to parse the records to get the code or address and print it.

if (response.statusCode == 200) {
  print(response.body);
  final responseJson = json.decode(response.body);
  var da=Pickup.fromJson(responseJson);
  Results dat=da.results;
  records data=dat.Records;
  print(data.address);
}

The response.body is working fine but when I try to parse results or records I got 'List' is not a subtype of type 'Map<String, dynamic>' error

I will definitely recommend you this website json to dart App Quicktype just don't forget to select Dart in the right side.

You just put your json in la left and in will give you something like this:

// To parse this JSON data, do
//
//     final pickUp = pickUpFromJson(jsonString);

import 'dart:convert';

PickUp pickUpFromJson(String str) => PickUp.fromJson(json.decode(str));

String pickUpToJson(PickUp data) => json.encode(data.toJson());

class PickUp {
    Results results;

    PickUp({
        this.results,
    });

    factory PickUp.fromJson(Map<String, dynamic> json) => new PickUp(
        results: Results.fromJson(json["results"]),
    );

    Map<String, dynamic> toJson() => {
        "results": results.toJson(),
    };
}

class Results {
    String totalRecordCount;
    List<Record> records;
    String result;

    Results({
        this.totalRecordCount,
        this.records,
        this.result,
    });

    factory Results.fromJson(Map<String, dynamic> json) => new Results(
        totalRecordCount: json["TotalRecordCount"],
        records: new List<Record>.from(json["Records"].map((x) => Record.fromJson(x))),
        result: json["Result"],
    );

    Map<String, dynamic> toJson() => {
        "TotalRecordCount": totalRecordCount,
        "Records": new List<dynamic>.from(records.map((x) => x.toJson())),
        "Result": result,
    };
}

class Record {
    String code;
    String address;
    String contactPhone;

    Record({
        this.code,
        this.address,
        this.contactPhone,
    });

    factory Record.fromJson(Map<String, dynamic> json) => new Record(
        code: json["code"],
        address: json["address"],
        contactPhone: json["contact_phone"],
    );

    Map<String, dynamic> toJson() => {
        "code": code,
        "address": address,
        "contact_phone": contactPhone,
    };
}

at the beginning it will tell you how you can use it.

// To parse this JSON data, do
//
//     final pickUp = pickUpFromJson(jsonString);

So when you call it in you code its gonna be something like this.

  Future<Pickup> getPickup() async {
    var response = await http.get(url);
    return pickUpFromJson(response.body);
  }

This code could be call for a FutureBuilder for example or wherever you set the code to wait for a future.

I have trouble getting data from a complex json, below is the json in the request.

{
   "results":{
      "TotalRecordCount":"1",
      "Records":[
         {
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         }
      ],
      "Result":"OK"
   }
}

Below is the model I made.

import 'dart:convert';

class Pickup {
  String status;
  List message;
  //Map<String ,dynamic> results;
  Results results;
  Pickup(
    {this.status,
     this.message,
     this.results,
  });
  factory Pickup.fromJson(Map<String, dynamic> json) {
    return Pickup(
             status: json["status"] as String,
             results: Results.fromJson(json["results"]),

           );
  }
}

class Results {
  String TotalRecordCount;
  records Records;

  Results({this.TotalRecordCount,this.Records});

  factory Results.fromJson(Map<String, dynamic> json) {
    return Results(
    TotalRecordCount: json["TotalRecordCount"],
    Records:records.fromJson(json["Records"]),

    );
  }
}

class records{
  String code;
  String address;
  String contact_phone;

  records({
    this.code,
    this.address,
    this.contact_phone
  });

  factory records.fromJson(Map<String, dynamic> json) {
    return records(
      code: json["code"],
      address: json["address"],
      contact_phone: json["contact_phone"],
    );
  }
}

Now Im trying to parse the records to get the code or address and print it.

if (response.statusCode == 200) {
  print(response.body);
  final responseJson = json.decode(response.body);
  var da=Pickup.fromJson(responseJson);
  Results dat=da.results;
  records data=dat.Records;
  print(data.address);
}

The response.body is working fine but when I try to parse results or records I got 'List' is not a subtype of type 'Map<String, dynamic>' error

An example of how this can be done.

import 'dart:convert';

import 'json_objects.dart';

void main() {
  final responseJson = json.decode(responseBody) as Map<String, dynamic>;
  var da = Pickup.fromJson(responseJson);
  Results dat = da.results;
  List<ResultsRecords> data = dat.records;
  print(data[0].address);
}

var responseBody = '''
{
   "results":{
      "TotalRecordCount":"1",
      "Records":[
         {
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         }
      ],
      "Result":"OK"
   }
}''';

Result:

1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000

Source code of used data models.

class Pickup {
  final Results results;

  Pickup({this.results});

  factory Pickup.fromJson(Map<String, dynamic> json) {
    return Pickup(
      results: _toObject(json['results'], (e) => Results.fromJson(e)),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'results': results?.toJson(),
    };
  }
}

class Results {
  final List<ResultsRecords> records;
  final String result;
  final String totalRecordCount;

  Results({this.records, this.result, this.totalRecordCount});

  factory Results.fromJson(Map<String, dynamic> json) {
    return Results(
      records:
          _toObjectList(json['Records'], (e) => ResultsRecords.fromJson(e)),
      result: json['Result'] as String,
      totalRecordCount: json['TotalRecordCount'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'Records': _fromList(records, (e) => e.toJson()),
      'Result': result,
      'TotalRecordCount': totalRecordCount,
    };
  }
}

class ResultsRecords {
  final String address;
  final String code;
  final String contactPhone;

  ResultsRecords({this.address, this.code, this.contactPhone});

  factory ResultsRecords.fromJson(Map<String, dynamic> json) {
    return ResultsRecords(
      address: json['address'] as String,
      code: json['code'] as String,
      contactPhone: json['contact_phone'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'address': address,
      'code': code,
      'contact_phone': contactPhone,
    };
  }
}

List _fromList(data, Function(dynamic) toJson) {
  if (data == null) {
    return null;
  }
  var result = [];
  for (var element in data) {
    var value;
    if (element != null) {
      value = toJson(element);
    }
    result.add(value);
  }
  return result;
}

T _toObject<T>(data, T Function(Map<String, dynamic>) fromJson) {
  if (data == null) {
    return null;
  }
  return fromJson(data as Map<String, dynamic>);
}

List<T> _toObjectList<T>(data, T Function(Map<String, dynamic>) fromJson) {
  if (data == null) {
    return null;
  }
  var result = <T>[];
  for (var element in data) {
    T value;
    if (element != null) {
      value = fromJson(element as Map<String, dynamic>);
    }
    result.add(value);
  }
  return result;
}

/*
Pickup:
  "results": Results

Results:
  "TotalRecordCount": String
  "Records": List<ResultsRecords>
  "Result": String

ResultsRecords:
  "code": String
  "address": String
  "contact_phone": String
*/

{
   "results":{
      "TotalRecordCount":"1",
      "Records":[
         {
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         }
      ],
      "Result":"OK"
   }
}

The above JSON file consists of a list of "Records" within it hence making it a complex JSON. Below are the amendments I would like to contribute to the code -

class Pickup {
  String status;
  List message;
  //Map<String ,dynamic> results;
  Results results;
  Pickup(
    {this.status,
     this.message,
     this.results,
  });
  factory Pickup.fromJson(Map<String, dynamic> json) {
    return Pickup(
             status: json["status"] as String,
             results: Results.fromJson(json["results"]),

           );
  }
}
class Results {
  String TotalRecordCount;
  records Records;

  Results({this.TotalRecordCount,this.Records});



    factory Results.fromJson(Map<String, dynamic> json) {
        //since records is a list hence it is parsed separately by creating a 
        //list out of it.  
    



       listOfRecords = (json["Records"] as List)
      .map((i) => records.fromJson(i))
      .toList();


 
    return Results(
    TotalRecordCount: json["TotalRecordCount"],
    Records:listOfRecords //now the list is used here directly
),

    );
  }
}

class records{
  String code;
  String address;
  String contact_phone;

  records({
    this.code,
    this.address,
    this.contact_phone
  });

  factory records.fromJson(Map<String, dynamic> json) {
    return records(
      code: json["code"],
      address: json["address"],
      contact_phone: json["contact_phone"],
    );
  }

At last, we can use this wherever it is required like this -

if (response.statusCode == 200) {
  print(response.body);
  final responseJson = json.decode(response.body);
  var da = Pickup.fromJson(responseJson);
  Results dat = da.results;
  records data = dat.Records;
  print(data[0].address);  //since records was a list
}

For such a case, only one class is enough.
An example of how this can be done.

import 'package:fast_json/fast_json_selector.dart' as parser;

void main(List<String> args) async {
  final records = _parseRecords(_data);
  print('Found: ${records.length} records(s).');
  print(records.map((e) => e.code).join('\n'));
}

const _data = '''
{
   "results":{
      "TotalRecordCount":"1",
      "Records":[
         {
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         }
      ],
      "Result":"OK"
   }
}''';

List<Record> _parseRecords(String source) {
  // Path to Record
  // Map => 'results' => Map => 'records' => List => list index => Map (Record)
  final level = '{} results {} records [] 0 {}'.split(' ').length;
  final records = <Record>[];
  void select(parser.JsonSelectorEvent event) {
    if (event.levels.length == level) {
      final record = Record.fromJson(event.lastValue as Map);
      records.add(record);
      // Freeing the memory because it is no longer needed
      event.lastValue = null;
    }
  }

  parser.parse(source, select: select);
  return records;
}

class Record {
  String code;
  String address;
  String contact_phone;

  Record({
    required this.code,
    required this.address,
    required this.contact_phone,
  });

  factory Record.fromJson(Map json) {
    return Record(
      code: json["code"] as String,
      address: json["address"] as String,
      contact_phone: json["contact_phone"] as String,
    );
  }
}

Output:

Found: 1 records(s).
PCK_34333338365C93E2D50DB9C

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM