Related
How to parse from JSON to Dart object including 2 nested classes inside of properties oof the class, Lists?
A JSON object Video that contains a list of Question objects.
Question objects contains a list of Ans objects.
{
"id": 1,
"videoUrl": "https://assets.mixkit.co/videos/preview/mixkit-machinery-of-a-very-close-watch-3673-large.mp4",
"questions": [
{
"id": "0-903669-72-2",
"type": "mc",
"body": "Understand reality truth food agency artist.",
"correctAnswerId": "0-259-85157-4",
"ans": [
{
"id": "0-259-85157-4",
"body": "Play."
},
{
"id": "0-694-71578-6",
"body": "Whose trip."
},
{
"id": "0-13-124278-4",
"body": "Of figure why."
},
{
"id": "0-8169-6726-1",
"body": "Station culture green."
}
]
},
{
"id": "1-872297-31-5",
"type": "mc",
"body": "Especially resource benefit beautiful world six.",
"correctAnswerId": "1-61799-113-9",
"ans": [
{
"id": "0-384-69655-4",
"body": "Form."
},
{
"id": "0-89336-975-6",
"body": "Call."
},
{
"id": "1-61799-113-9",
"body": "Money three young."
},
{
"id": "1-60950-585-9",
"body": "Three threat back."
}
]
},
{
"id": "0-297-13339-X",
"type": "mc",
"body": "Of smile coach second firm ahead.",
"correctAnswerId": "1-916803-19-9",
"ans": [
{
"id": "0-15-955520-5",
"body": "Add old catch."
},
{
"id": "0-606-65499-2",
"body": "Well great task."
},
{
"id": "0-7364-1942-X",
"body": "Arrive resource speech kid."
},
{
"id": "1-916803-19-9",
"body": "Reach brother book."
}
]
},
{
"id": "0-254-52906-2",
"type": "ms",
"correctAnswers": [
"1-146-90255-7",
"0-17-470673-1"
],
"body": "Particularly affect but necessary.",
"ans": [
{
"id": "0-17-278557-X",
"body": "Response bill."
},
{
"id": "0-17-470673-1",
"body": "Attack sister interview."
},
{
"id": "0-16-027096-0",
"body": "Design garden."
},
{
"id": "1-146-90255-7",
"body": "Short break."
}
]
},
{
"id": "0-926285-49-1",
"type": "ms",
"correctAnswers": [
"0-554-50421-9",
"0-294-02768-8"
],
"body": "Experience family training.",
"ans": [
{
"id": "0-8260-5153-7",
"body": "Mouth exist kid."
},
{
"id": "0-294-02768-8",
"body": "Agreement factor."
},
{
"id": "0-554-50421-9",
"body": "Down race professional show."
},
{
"id": "1-124-45547-7",
"body": "Most such onto strategy."
}
]
}
]
}
I tried using this tool after failing to properly do this myself.
https://javiercbk.github.io/json_to_dart/
This is the class definitions I got(I changed some things because of VSCode suggestions).
class Video {
int? id;
String? videoUrl;
List<Question>? questions;
Video({this.id, this.videoUrl, this.questions});
Video.fromJson(Map<String, dynamic> json) {
id = json['id'];
videoUrl = json['videoUrl'];
if (json['questions'] != null) {
questions = <Question>[];
json['questions'].forEach((v) {
questions!.add(Question.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['videoUrl'] = videoUrl;
if (this.questions != null) {
data['questions'] = questions!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Question {
String? id;
String? type;
String? body;
String? correctAnswerId;
List<Ans>? ans;
List<String>? correctAnswers;
Question(
{this.id,
this.type,
this.body,
this.correctAnswerId,
this.ans,
this.correctAnswers});
Question.fromJson(Map<String, dynamic> json) {
id = json['id'];
type = json['type'];
body = json['body'];
correctAnswerId = json['correctAnswerId'];
if (json['ans'] != null) {
ans = <Ans>[];
json['ans'].forEach((v) {
ans!.add(Ans.fromJson(v));
});
}
correctAnswers = json['correctAnswers'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['type'] = type;
data['body'] = body;
data['correctAnswerId'] = correctAnswerId;
if (ans != null) {
data['ans'] = ans!.map((v) => v.toJson()).toList();
}
data['correctAnswers'] = correctAnswers;
return data;
}
}
class Ans {
String? id;
String? body;
Ans({this.id, this.body});
Ans.fromJson(Map<String, dynamic> json) {
id = json['id'];
body = json['body'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['body'] = body;
return data;
}
}
I load the JSON like this.
getVid() async {
final String response = await rootBundle.loadString('assets/videos.json');
final data = await json.decode(response)['videos'];
List<Video> vids = List<Video>.from(data.map((x) => Video.fromJson(x)));
}
But end up with this error message inside of the console.
Uncaught (in promise) Error: NoSuchMethodError: 'cast'
Dynamic call of null.
Receiver: null
Arguments: []
Your help is greatly appreciated!
This line of code correctAnswers = json['correctAnswers'].cast<String>(); is causing error, as it is not able to cast it as list of string
Try using List.from() or map() or List.of()methods
correctAnswers = List<String>.from(json['correctAnswers']);
Or
correctAnswers = json['correctAnswers'].map((answer) => answer.toString()).toList();
Or
correctAnswers = List<String>.of(json['correctAnswers']);
I have tried several ways to access the data but the result is still the same where the type is a map and I can't convert it to a list of my model so I hope to get some help and I am thankful to you
my Repo
Future getdata(apiUrl) async {
http.Response response = await http.get(Uri.parse(_url + apiUrl));
try {
if (response.statusCode == 200) {
print('dtaa serve done 200');
var body= jsonDecode(response.body);
print(body.runtimeType);
print(body.runtimeType);
return body;
} else {
print("its empty first");
return {};
}
} catch (e) {
print(e.toString() + "first");
return {};
}
my Cubit
void getSBranchData(Service service) async {
try { print("loding SBranchData");
sBranches = await repo.getSBranches(service.id);
print(sBranches.toString()+" Cubit");
emit(SBranchDataState(sBranches,service));
print("loded SBranchData");
} catch (e) {
print(e.toString() + "sec");
}
is this Right
my model
SBranch(
{this.id,
this.sbranchName,
this.sbranchDisc,
this.sbranchImg,
this.parentSbranch,
this.serviceId,
this.childSbranch});
SBranch.fromJson(Map<String, dynamic> json) {
id = json['id'];
sbranchName = json['sbranch_name'];
sbranchDisc = json['sbranch_disc'];
sbranchImg = json['sbranch_img'];
parentSbranch = json['parent_sbranch'];
serviceId = json['service_id'];
if (json['child_sbranch'] != null) {
childSbranch = <ChildSbranch>[];
json['child_sbranch'].forEach((v) {
childSbranch!.add(new ChildSbranch.fromJson(v));
});
json
[
{
"id": 1,
"sbranch_name": "mn,.m.",
"sbranch_disc": "lmlmlm.",
"sbranch_img": "",
"parent_sbranch": 0,
"service_id": "1",
"child_sbranch": [
{
"id": 3,
"sbranch_name": "mn,.m.",
"sbranch_disc": "lmlmlm.",
"sbranch_img": "",
"parent_sbranch": 1,
"service_id": "",
"child_sbranch": []
}
]
},
{
"id": 2,
"sbranch_name": "mn,.m.",
"sbranch_disc": "lmlmlm.",
"sbranch_img": "",
"parent_sbranch": 0,
"service_id": "2",
"child_sbranch": [
{
"id": 4,
"sbranch_name": "mn,.m.",
"sbranch_disc": "lmlmlm.",
"sbranch_img": "",
"parent_sbranch": 2,
"service_id": "",
"child_sbranch": []
}
]
},
{
"id": 3,
"sbranch_name": "mn,.m.",
"sbranch_disc": "lmlmlm.",
"sbranch_img": "",
"parent_sbranch": 1,
"service_id": "",
"child_sbranch": []
},
{
"id": 4,
"sbranch_name": "mn,.m.",
"sbranch_disc": "lmlmlm.",
"sbranch_img": "",
"parent_sbranch": 2,
"service_id": "",
"child_sbranch": []
}
]
thanks for your Time
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv** *
v*
I have try to put my JSON data in flutter Stacked Chart.
I already work on simple charts using JSON Data like bar, column, pie, Doughnut charts etc.
I have refer
stacked-column-chart(syncfusion_flutter_charts),
Grouped Bar Chart(charts_flutter)
Stack Overflow Que-Ans
below like my API response/JSON String
[{
"name": "ABC",
"subject": [{
"name": "Math",
"marks": "54"
},
{
"name": "Physics",
"marks": "65"
}
]
},
{
"name": "PQR",
"subject": [{
"name": "Chemistry",
"marks": "53"
},
{
"name": "Biology",
"marks": "22"
},
{
"name": "English",
"marks": "7 "
},
{
"name": "Math",
"marks": "12"
}
]
}, {
"name": "JKL",
"subject": [{
"name": "Chemistry",
"marks": "53"
},
{
"name": "Biology",
"marks": "22"
},
{
"name": "English",
"marks": "79 "
},
{
"name": "Math",
"marks": "12"
},
{
"name": "Physics",
"marks": "72"
}
]
}
]
Or I want below type of graph using JSON Data
Note: Suggest me my JSON string is wrong, you can create your own JSON data and display the output
Using charts_flutter. Please customize it for your usecase its a bare minimum implementation to validate that its working for your json.
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'dart:convert';
class StackedBarChart extends StatelessWidget {
final bool animate;
StackedBarChart({this.animate = false});
// EXCLUDE_FROM_GALLERY_DOCS_END
#override
Widget build(BuildContext context) {
String jsonString = '[{"name":"ABC","subject":[{"name":"Math","marks":"54"},{"name":"Physics","marks":"65"}]},{"name":"PQR","subject":[{"name":"Chemistry","marks":"53"},{"name":"Biology","marks":"22"},{"name":"English","marks":"7 "},{"name":"Math","marks":"12"}]},{"name":"JKL","subject":[{"name":"Chemistry","marks":"53"},{"name":"Biology","marks":"22"},{"name":"English","marks":"79 "},{"name":"Math","marks":"12"},{"name":"Physics","marks":"72"}]}]';
final studentMarks = studentMarksFromJson(jsonString);
var subjects = <Subject?>{};
var subjectsDist = <Subject?>{};
int c=0;
for (var stdnt in studentMarks) {
for (var subjs in stdnt.subject) {
if (!subjectsDist.where((element) => element?.name==subjs.name).isNotEmpty) {
subjs.sno=c++;
subjectsDist.add(subjs);
}
}
}
print(subjectsDist.length);
List<List<OrdinalMarks>> SubjectData = [];
for (var subjs in subjectsDist) {
List<OrdinalMarks> marksData = [];
for (var stdnt in studentMarks) {
if (stdnt.subject
.where((element) => element.name == subjs?.name).isNotEmpty) {
var temp = stdnt.subject
.where((element) => element.name == subjs?.name)
.first;
marksData.add(OrdinalMarks(temp.name, int.parse(temp.marks),stdnt.name));
} else {
marksData.add(OrdinalMarks(subjs!.name, 0,stdnt.name));
}
}
SubjectData.add(marksData);
}
var palettes = charts.MaterialPalette.getOrderedPalettes(subjectsDist.length+2);
int cnt=0;
List<charts.Series<OrdinalMarks, String>> chartData = [
];
for(var d in SubjectData)
{
chartData.add(new charts.Series<OrdinalMarks, String>(
id: d.first.subjectName,
domainFn: (OrdinalMarks m, _) => m.studentName,
measureFn: (OrdinalMarks m, _) => m.marks,
data: d,
fillColorFn: ( subj, _) {
// print(subj.subjectName+": subj.subjectName :" + pallets[subj.subjectName].toString()??charts.MaterialPalette.blue.shadeDefault.toString());
return palettes.elementAt( subjectsDist.where((element) => element?.name==subj.subjectName).first?.sno??0 ).shadeDefault; //pallets[subj.subjectName]??charts.MaterialPalette.blue.shadeDefault;
},
colorFn: ( subj, _) {
// print(subj.subjectName+": subj.subjectName :" + pallets[subj.subjectName].toString()??charts.MaterialPalette.blue.shadeDefault.toString());
return palettes.elementAt(subjectsDist.where((element) => element?.name==subj.subjectName).first?.sno??0).shadeDefault;
},
));
}
return Scaffold(
// Use Obx(()=> to update Text() whenever count is changed.
appBar: AppBar(title: Text("Chart")),
// Replace the 8 lines Navigator.push by a simple Get.to(). You don't need context
body:new charts.BarChart(
chartData,
animate: animate,
behaviors: [new charts.SeriesLegend(showMeasures: true)],
animationDuration: Duration(seconds: 3),
));
}
}
/// Sample ordinal data type.
class OrdinalMarks {
final String subjectName;
final int marks;
final String studentName;
OrdinalMarks(this.subjectName, this.marks,this.studentName);
}
List<StudentMarks> studentMarksFromJson(String str) => List<StudentMarks>.from(json.decode(str).map((x) => StudentMarks.fromJson(x)));
String studentMarksToJson(List<StudentMarks> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class StudentMarks {
StudentMarks({
required this.name,
required this.subject,
});
String name;
List<Subject> subject;
factory StudentMarks.fromJson(Map<String, dynamic> json) => StudentMarks(
name: json["name"],
subject: List<Subject>.from(json["subject"].map((x) => Subject.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"name": name,
"subject": List<dynamic>.from(subject.map((x) => x.toJson())),
};
}
class Subject {
Subject({
required this.name,
required this.marks,
});
String name;
String marks;
int? sno;
factory Subject.fromJson(Map<String, dynamic> json) => Subject(
name: json["name"],
marks: json["marks"],
);
Map<String, dynamic> toJson() => {
"name": name,
"marks": marks,
};
}
i have a json
{
"result": [
{
"id": 2,
"e_id": 2,
"e_name": "0",
"abc": 0,
"doa": "2021-02-15 13:17:11"
},
{
"id": 3,
"e_id": 22,
"e_name": "ok",
"abc": 1,
"doa": "2021-02-15 13:17:57"
}
],
"status": 1,
"msg": "Successfully fetched"
}
.
How i want two list like
List keyList=[
"id","e_id","e_name","abc","doa"];
and
List valueList=[
{
2, 2,"0",0,"2021-02-15 13:17:11"
},
{
3, 22,"ok",1,"2021-02-15 13:17:57"
}
];
anyOne who can help me??
how to get list of keys and list of value, both are separate lists and fetch only from single json which is given above.
here is my model class---
class DataModel {
List<Result> result;
int status;
String msg;
DataModel({this.result, this.status, this.msg});
DataModel.fromJson(Map<String, dynamic> json) {
if (json['result'] != null) {
result = new List<Result>();
json['result'].forEach((v) {
result.add(new Result.fromJson(v));
});
}
status = json['status'];
msg = json['msg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.result != null) {
data['result'] = this.result.map((v) => v.toJson()).toList();
}
data['status'] = this.status;
data['msg'] = this.msg;
return data;
}
}
class Result {
int id;
int eId;
String eName;
String abc;
String doa;
Result(
{this.id,
this.eId,
this.eName,
this.abc,
this.doa});
Result.fromJson(Map<String, dynamic> json) {
id = json['id'];
eId = json['e_id'];
eName = json['e_name'];
abc= json['abc'];
doa = json['doa'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['e_id'] = this.eId;
data['e_name'] = this.eName;
data['abc'] = this.abc;
data['doa'] = this.doa;
return data;
}
}
i dont need model mapping,
i need only two different list- one is keyList and other one is valuelist form the result.
kindly help me to get this lists
Map<String, dynamic> json ={
"result": [
{
"id": 2,
"e_id": 2,
"e_name": "0",
"abc": 0,
"doa": "2021-02-15 13:17:11"
},
{
"id": 3,
"e_id": 22,
"e_name": "ok",
"abc": 1,
"doa": "2021-02-15 13:17:57"
}
],
"status": 1,
"msg": "Successfully fetched"
};
List<String> keyList;
List<List<dynamic>> valueList = [];
json["result"].forEach((entry) {
keyList ??= entry.keys;
valueList.add(entry.values);
});
Here is the code which gives you key and values as a List:
You can copy and try it out on dartpad.dev
import 'dart:convert';
String json = '''
{
"result": [
{
"id": 2,
"e_id": 2,
"e_name": "0",
"abc": 0,
"doa": "2021-02-15 13:17:11"
},
{
"id": 3,
"e_id": 22,
"e_name": "ok",
"abc": 1,
"doa": "2021-02-15 13:17:57"
}
],
"status": 1,
"msg": "Successfully fetched"
}
''';
void main() {
Map<String, dynamic> map = jsonDecode(json);
List<String> keyList = map['result'][0].keys.toList();
List<dynamic> listOfValues = [];
List<dynamic> valueList = map['result'];
for(int i=0; i < valueList.length; i++) {
Map<String, dynamic> obj = valueList[i];
listOfValues.addAll(obj.values);
}
keyList.forEach(print);
print('\n\n');
listOfValues.forEach(print);
}
Output by printing each element of both arrays:
id
e_id
e_name
abc
doa
2
2
0
0
2021-02-15 13:17:11
3
22
ok
1
2021-02-15 13:17:57
Use rootBundle.loadString('assets/json_file.json');
and then json.decode(jsonString);
Now you can use it normally
I would want to get the data for all "name" only from the array data.
I want to print(data['data']['name']);
But it returns this error:
Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
But when I print(data['data']);, it will return all data from "data":
"data": [
{
"created_at": "2020-03-16 16:10:51",
"deleted_at": null,
"id": 2,
"is_active": 1,
"name": "Maybank",
"updated_at": "2020-03-16 16:18:06"
},
{
"created_at": "2020-03-16 16:27:37",
......
],
Call API Code
displayBanks(BuildContext context) async {
_callApi.refreshTokenApi(context);
var _addressUrl = '$_hostUrl/banks'; //API URL
final SharedPreferences prefs = await SharedPreferences.getInstance();
_accessToken = prefs.getString('access_token');
Response _response = await get(_addressUrl, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $_accessToken'
});
var data;
data = jsonDecode(_response.body);
if (_response.statusCode == 200) {
print(data['data']['name']);
return data;
}
else {
print(_response.statusCode);
}
}
SAMPLE JSON DATA FROM API URL:
{
"data": [
{
"created_at": "2020-03-16 16:10:51",
"deleted_at": null,
"id": 2,
"is_active": 1,
"name": "Maybank",
"updated_at": "2020-03-16 16:18:06"
},
{
"created_at": "2020-03-16 16:27:37",
"deleted_at": null,
"id": 3,
"is_active": 1,
"name": "India International Bank (Malaysia) Berhad",
"updated_at": "2020-03-16 16:27:37"
},
{
"created_at": "2020-03-16 16:27:37",
"deleted_at": null,
"id": 4,
"is_active": 1,
"name": "National Bank of Abu Dhabi Malaysia Berhad",
"updated_at": "2020-03-16 16:27:37"
}
],
"links": {
"first": "https://demo.local/api/banks?page=1",
"last": "https://demo.local/api/banks?page=1",
"next": null,
"prev": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"path": "https://demo.local/api/banks",
"per_page": 5,
"to": 3,
"total": 3
}
}
Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
The exception message explains the issue clearly.
The property 'name' is inside an object which itself placed in an array. So you first decode the array. Then access each object using the index (0..n), then from each object, you can read the 'name' property.
Here you go
class MyData {
final List<Data> data;
MyData({this.data});
factory MyData.fromJson(Map<String, dynamic> json) {
return MyData(
data: json['data'] != null ? (json['data'] as List).map((i) => Data.fromJson(i)).toList() : null,
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
final String created_at;
final String deleted_at;
final int id;
final int is_active;
final String name;
final String updated_at;
Data({this.created_at, this.deleted_at, this.id, this.is_active, this.name, this.updated_at});
factory Data.fromJson(Map<String, dynamic> json) {
return Data(
created_at: json['created_at'],
deleted_at: json['deleted_at'],
id: json['id'],
is_active: json['is_active'],
name: json['name'],
updated_at: json['updated_at'],
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['created_at'] = this.created_at;
data['id'] = this.id;
data['is_active'] = this.is_active;
data['name'] = this.name;
data['updated_at'] = this.updated_at;
data['deleted_at'] = this.deleted_at;
return data;
}
}
The error makes sense. The 'data' attribute in your JSON is array. So, you'll have to pass index of the item to access 'name' attribute - something like - data['data'][0]['name'] to get 'Maybank'.
Ideally, you should have a class which creates the instance from the JSON. In this case, the code snippet will look like :
Banks banks = new Banks.fromJson(data)
Now, you can use sites like this to create a class definition (including.fromJson).