I need to merge nested json to simple json in dart flutter - json

I need to merge nested json to simple json here is the response from API
{
"1": [
{
"id": 6,
"name": "test 1"
},
{
"id": 8,
"name": "test 2"
},
{
"id": 7,
"name": "test 3"
}
],
"2": [
{
"id": 9,
"name": "ttt1"
},
{
"id": 5,
"name": "ttt3"
}
],
"3": [
{
"id": 4,
"name": "ttg"
}
]
}
How i need is
[
{
"id": 4,
"name": null
},
{
"id": 6,
"name": null
},
{
"id": 8,
"name": null
},
{
"id": 9,
"name": null
},
{
"id": 5,
"name": null
},
{
"id": 7,
"name": null
}
]
Here is my model
class HomeBannerModel {
int id;
String name;
HomeBannerModel({this.id, this.name});
HomeBannerModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
image = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
SO here is my looping part
var responseList = response.data['data'];
if (response.data['success'] == true) {
List data = [];
responseList.forEach((k, v) {
var value =
v.map((banner) => HomeBannerModel.fromJson(banner)).toList();
data.add(value);
});
print(data);
but i am getting error as 'length' was called on null. so let me know where i am missing since i amnew to dart the api is giving numeric as key so i am facing the difficulty in getting the data

Maybe you can try this
List<HomeBannerModel> data = [];
responseList.forEach((key, value) {
value.forEach((element) {
data.add(HomeBannerModel.fromJson(element));
});
});

Related

Parse JSON to Dart with nested List objects

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']);

type '(dynamic) => SBranch' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform

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*

Put JSON Data in Flutter Stacked Chart

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,
};
}

how to get list of keys and list of value from a single json in flutter

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

How to get json array in Flutter/Dart

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).