Reputation: 121
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
Upvotes: 11
Views: 17623
Reputation: 11218
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
Upvotes: 0
Reputation: 501
{
"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
}
Upvotes: 0
Reputation: 622
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.
Upvotes: 24