Flutter json Unhandled Exception type - json

i have a problem with a json response
Json it's:
{
"SData": {
"total": "1",
"STable": {
"year": "2020",
"S1Lists": [
{
"year": "2020",
"turn": "6",
"Ranking": [
{
"position": "1",
"Person": {
"personId": "paul",
"nationality": "none"
},
},
]
}
]
}
}
Dart code
if(response.statusCode == 200){
final result = response.data;
Iterable list = result['SData'];
print(list);
}else{
throw Exception("Fail!");
}
and i receive this error
Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>'
how can i solve if, for example, i want to access the position field or the personId field

This happens because your json output is a Map<String, dynamic> and not a Iterable.
if (response.statusCode == 200) {
final result = response.data;
final Map<String, dynamic> map = result['SData'];
print(map );
} else {
throw Exception("Fail!");
}
Which will print this output
{
"total":1,
"STable":{
"year":2020,
"S1Lists":[
{
"year":2020,
"turn":6,
"Ranking":[
{
"position":1,
"Person":{
"personId":"paul",
"nationality":"none"
}
}
]
}
]
}
}
If you want to get the ranking.
final Map<String, dynamic> data = result ['SData'];
final Map<String, dynamic> table = data['STable']; // This is like result['SData']['STable']
final Map<String, dynamic> list = table['S1Lists']; // result['SData']['STable']['S1Lists']
final Map<String, dynamic> firstItem = list[0]; // result['SData']['STable']['S1Lists'][0]
final Map<String, dynamic> ranking = list['Ranking']; // result['SData']['STable']['S1Lists'][0]['Ranking']

Related

Try to access in flutter a map inside a map from json but won´t work

i call an api with
Future<ApiData> fetchData() async {
final response = await http
.get(Uri.parse(
'https://apilink.com'));
if (response.statusCode == 200) {
Map<String, dynamic> jsonResponse = json.decode(response.body);
return ApiData.fromJson(jsonDecode(response.body));
}
and have a json file like this:
{
"data": {
"base_data": {
"US": {
"org_data": {
"country_full_name": "UNITED STATES",
"size": "large"
},
"user_data": {
"amount": 1.0,
"owned_in_total_euro": 100
}
},
"DE": {
"org_data": {
"country_full_name": "Germany",
"size": "medium"
},
"user_data": {
"amount": 5.0,
"owned_in_total_euro": 400
}
}
},
"calc_data": {
"country": {
"United States": 1.0
"Germany": 5.0
"Poland": 4.5
},
"currency": {
"USD": 1.0
"EUR": 2.0
}
}
}
}
In jsonReponse is a map with 1 item => 0: "data" -> Map (2 items)
This is a map with maps inside with other maps or lists inside and they are dynamice like this:
Map
Map1
MapABC
MapXYZ
List
Map2
List
MapX
I tried a lot of things like this but nothing worked:
//data map
Map<String, dynamic> jsonResponse = json.decode(response.body);
//base_data & calc_data inside data
Map<dynamic, dynamic> jsonResponse2 = Map.from(jsonResponse);
Question:
How can I access this in flutter?
Do you have any examples of info on this for me?
I tryed a lot with stuff I found in google and the decode-help but can´t find out how to process a (dynamic)-map in a map.
Thanks in advance
Patrick
Update:
I added this to my model:
#JsonSerializable(explicitToJson: true)
class BackendCalcData {
List<BackendCalcDataCountry>? backendCountry;
List<BackendCalcDataCurrency>? backendCurrency;
BackendCalcData({
List<BackendCalcDataCountry>? backendCountry,
List<BackendCalcDataCurrency>? backendCurrency,
});
factory BackendCalcData.empty() {
return BackendCalcData();
}
factory BackendCalcData.fromJson(Map<String, dynamic> json) =>
_$BackendCalcDataFromJson(json);
Map<String, dynamic> toJson() => _$BackendCalcDataToJson(this);
}
#JsonSerializable()
class BackendCalcDataCountry {
String countryName;
double countryRatio;
BackendCalcDataCountry({
this.countryName = "",
this.countryRatio = 0,
});
factory BackendCalcDataCountry.fromJson(Map<String, dynamic> json) =>
_$BackendCalcDataCountryFromJson(json);
Map<String, dynamic> toJson() => _$BackendCalcDataCountryToJson(this);
}
#JsonSerializable()
class BackendCalcDataCurrency {
String currencyCode;
double currencyRatetoEuro;
BackendCalcDataCurrency({
this.currencyCode = "",
this.currencyRatetoEuro = 0,
});
factory BackendCalcDataCurrency.fromJson(Map<String, dynamic> json) =>
_$BackendCalcDataCurrencyFromJson(json);
Map<String, dynamic> toJson() => _$BackendCalcDataCurrencyToJson(this);
}
And got the generated code.

How to parse dynamic JSON with Flutter?

I do not understand how to parse a JSON file I get from firebase.
This is the format of the JSON file
{
"water" : {
"-MnRJkFC3--ZOTmpF1xN" : {
"milliliters" : 0.14,
"time" : "16:26:25"
},
"-MnRJkZRwZYEInHfSKIY" : {
"milliliters" : 48.83,
"time" : "16:26:25"
},
"-MnRJksES18hY765rxxq" : {
"milliliters" : 41.44,
"time" : "16:26:25"
},
"-MnRJlDn6o4RmiGRJS-E" : {
"milliliters" : 11.37,
"time" : "16:26:25"
}
}
}
This is how I am reading the JSON file
Future loadSalesData() async {
final String jsonString = await getJsonFromFirebase();
final dynamic jsonResponse = json.decode(jsonString);
for (Map<String, dynamic> i in jsonResponse)
chartData.add(SalesData.fromJson(i));
}
The getJsonFromFirebase() looks like this:
Future<String> getJsonFromFirebase() async {
String url =
"https://emailpassword. . .seio.com/water.json";
http.Response response = await http.get(Uri.parse(url));
return response.body;
}
When you click on the link it send you to the JSON file which looks like this
{
"-Mnbk2ye2P8bfpaQvNaU": {
"milliliters": 0.0,
"time": "18:07:00"
},
"-Mnbk6wd-wJze8P0JknK": {
"milliliters": 0.12,
"time": "18:07:00"
},
"-Mnbk7Ek629vgBu-MiLg": {
"milliliters": 44.91,
"time": "18:07:00"
},
"-Mnbk7bPuzqwsz9d5nm6": {
"milliliters": 5.43,
"time": "18:07:00"
},
"-Mnbk7v7MADi7YzEbeFI": {
"milliliters": 24.54,
"time": "18:07:00"
},
"-Mnbk8DGfqswckdsA1qP": {
"milliliters": 47.58,
"time": "18:07:00"
},
"-Mnbk8Xw2kJPxLrqCl6h": {
"milliliters": 13.98,
"time": "18:07:00"
}
}
I get the Error
_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable'
With the shape of the JSON you are receiving, json.decode will return a Map<String, dynamic> (more specifically an instance of the _InternalLinkedHashMap<String, dynamic> specialisation). This type doesn't implement Iterable, so you can't iterate over it directly with the for-in construct, and this is the exact error you are getting, at run time.
Depending on what you need to construct your SalesData instance, you have two options:
iterate over the entries property, if you need the key of each item ("-Mnbk2ye2P8bfpaQvNaU", "-Mnbk6wd-wJze8P0JknK" etc), otherwise
iterate over the values property, if you don't
Entries
Iteration:
for (MapEntry<String, dynamic> i in jsonResponse.entries) {
chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson:
SalesData.fromJson(MapEntry<String, dynamic> data) {
id = data.key;
milliliters = data.value['milliliters'];
time = data.value['time'];
}
Values
Iteration:
for (Map<String, dynamic> i in jsonResponse.values) {
chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson:
SalesData.fromJson(Map<String, dynamic> data) {
milliliters = data['milliliters'];
time = data['time'];
}
Type Inference
Additionally, regardless of how you decide to iterate over the Map instance, you can clean up the code a little taking advantage of Dart's type inference, so (presuming you are iterating over the entries) loadSalesData could become:
Future loadSalesData() async {
final jsonString = await getJsonFromFirebase();
final jsonResponse = json.decode(jsonString);
for (final i in jsonResponse.entries) {
chartData.add(SalesData.fromJson(i));
}
}
and getJsonFromFirebase could become:
Future<String> getJsonFromFirebase() async {
final url = "http://localhost:8080/data.json";
final response = await http.get(Uri.parse(url));
return response.body;
}
It seems flutter does not understand that jsonResponse is an iterable because you defined it as dynamic.
Adjust the definition to tell flutter it is a map:
final Map<String, dynamic> jsonResponse = json.decode(jsonString);

error when trying to decode json and casting it

I am trying to decode complex json data and always resulting in error.
Below are my json data:
{
"status_code": 200,
"message": "Successfully get data user",
"data": {
"sec_user": {
"clientIp": "1.4.2.54",
"officeid": "N/A",
},
"username": "uname",
"name1": "",
"menus": [
{
"appl_id": "MTC",
"menu_caption": "Master",
"menu_path": "/master",
"submenus": [
{
"menu_caption": "Machine List",
"note1": "master",
"sub_menu_id": "1",
"route_path": "/machine_list"
},
{
"menu_caption": "Sparepart Category",
"note1": "master",
"sub_menu_id": "1",
"route_path": "/sparepart_category"
}
]
},
{
"appl_id": "MTC",
"menu_caption": "Master",
"menu_path": "/master",
"submenus": [
{
"menu_caption": "Machine List",
"note1": "master",
"sub_menu_id": "1",
"route_path": "/machine_list"
}
]
},
]
}
}
and I already create a model class using json to dart (and already retouch it a bit) and use json annotation and build runner. Then I get an error everytime I tried to decode the body of this json
if (jsonResponse.statusCode == 200) {
final jsonItems =
json.decode(jsonResponse.body).cast<Map<String, dynamic>>();
List<Profile> profile = jsonItems.map<Profile>((json) {
return MyMenu.fromJson(json);
}).toList();
return profile;
}
I always get this error message (attached on the image bellow):
What when wrong with my code ?
End up answering my question, I did this:
json.decode(jsonResponse.body)['data']['menus'].cast<Map<String, dynamic>>();
Don't know if there is any other perfect method to do this.
Your json had some syntax error as well.Please try this it if helps
import 'dart:convert';
void main() {
var jsonData= {
"status_code": 200,
"message": "Successfully get data user",
"data": {
"sec_user": {
"clientIp": "1.4.2.54",
"officeid": "N/A"
},
"username": "uname",
"name1": "",
"menus": [
{
"appl_id": "MTC",
"menu_caption": "Master",
"menu_path": "/master",
"submenus": [
{
"menu_caption": "Machine List",
"note1": "master",
"sub_menu_id": "1",
"route_path": "/machine_list"
},
{
"menu_caption": "Sparepart Category",
"note1": "master",
"sub_menu_id": "1",
"route_path": "/sparepart_category"
}
]
},
{
"appl_id": "MTC",
"menu_caption": "Master",
"menu_path": "/master",
"submenus": [
{
"menu_caption": "Machine List",
"note1": "master",
"sub_menu_id": "1",
"route_path": "/machine_list"
}
]
}
]
}
};
final jsonItems =
ApiResponse.fromJson(jsonData);
print(jsonItems.message);
}
class ApiResponse {
int statusCode;
String message;
Data data;
ApiResponse({this.statusCode, this.message, this.data});
ApiResponse.fromJson(Map<String, dynamic> json) {
statusCode = json['status_code'];
message = json['message'];
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status_code'] = this.statusCode;
data['message'] = this.message;
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
class Data {
SecUser secUser;
String username;
String name1;
List<Menus> menus;
Data({this.secUser, this.username, this.name1, this.menus});
Data.fromJson(Map<String, dynamic> json) {
secUser = json['sec_user'] != null
? new SecUser.fromJson(json['sec_user'])
: null;
username = json['username'];
name1 = json['name1'];
if (json['menus'] != null) {
menus = new List<Menus>();
json['menus'].forEach((v) {
menus.add(new Menus.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.secUser != null) {
data['sec_user'] = this.secUser.toJson();
}
data['username'] = this.username;
data['name1'] = this.name1;
if (this.menus != null) {
data['menus'] = this.menus.map((v) => v.toJson()).toList();
}
return data;
}
}
class SecUser {
String clientIp;
String officeid;
SecUser({this.clientIp, this.officeid});
SecUser.fromJson(Map<String, dynamic> json) {
clientIp = json['clientIp'];
officeid = json['officeid'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['clientIp'] = this.clientIp;
data['officeid'] = this.officeid;
return data;
}
}
class Menus {
String applId;
String menuCaption;
String menuPath;
List<Submenus> submenus;
Menus({this.applId, this.menuCaption, this.menuPath, this.submenus});
Menus.fromJson(Map<String, dynamic> json) {
applId = json['appl_id'];
menuCaption = json['menu_caption'];
menuPath = json['menu_path'];
if (json['submenus'] != null) {
submenus = new List<Submenus>();
json['submenus'].forEach((v) {
submenus.add(new Submenus.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['appl_id'] = this.applId;
data['menu_caption'] = this.menuCaption;
data['menu_path'] = this.menuPath;
if (this.submenus != null) {
data['submenus'] = this.submenus.map((v) => v.toJson()).toList();
}
return data;
}
}
class Submenus {
String menuCaption;
String note1;
String subMenuId;
String routePath;
Submenus({this.menuCaption, this.note1, this.subMenuId, this.routePath});
Submenus.fromJson(Map<String, dynamic> json) {
menuCaption = json['menu_caption'];
note1 = json['note1'];
subMenuId = json['sub_menu_id'];
routePath = json['route_path'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['menu_caption'] = this.menuCaption;
data['note1'] = this.note1;
data['sub_menu_id'] = this.subMenuId;
data['route_path'] = this.routePath;
return data;
}
}

How to read json array from json response in flutter ? I am new in flutter Please help me

Below is my json response, i want to get this response into model and nested model class. Please help me to read this json. Thanks in advance. I am new in flutter to parse json response in model class.
'''
{
"success": 1,
"totalResults": 5,
"data": [
{
"id": 1,
"bank_name": "SBI bank",
"bank_logo": "http://3.143.33.201/assets/banklogo/1/sbi-round-logo.png",
"bank_desc": "sbi",
"rating": "AA"
},
{
"id": 2,
"bank_name": "Yes bank",
"bank_logo": "http://3.143.33.201/assets/banklogo/2/yes-round-logo.png",
"bank_desc": "Yes bank",
"rating": "AA"
},
{
"id": 3,
"bank_name": "Union bank",
"bank_logo": "http://3.143.33.201/assets/banklogo/3/union-round-logo.png",
"bank_desc": "union bank",
"rating": "AA"
},
{
"id": 9,
"bank_name": "Bank of Baroda",
"bank_logo": "http://3.143.33.201/assets/banklogo/9/bob.png",
"bank_desc": "Bank of Baroda",
"rating": "AA"
},
{
"id": 10,
"bank_name": "IndusInd Bank",
"bank_logo": "http://3.143.33.201/assets/banklogo/10/Indus-bank-2.png",
"bank_desc": "IndusInd Bank",
"rating": "AA"
}
]
}
'''
We have a inbuilt package in dart for it,
dart:convert, the usage is as follows
import 'dart:convert' as convert;
...
// perform your http request and get the response from it,
var responseData = convert.jsonDecode(response.body);
convert.jsonDecode() will enable accessing the data stores in the responseData with key values.
#note : I have imported it as convert as for my convenience as I don't get confused while development.
Happy coding
You can use JSON and serialization for this
final _response = jsonDecode(jsonResponse);
After that you can use _response data in your model class like this
YourModel.fromJson(_response);
Initialize your model and use like this
final YourModel _yourModel = YourModel();
final _isSuccess = _yourModel.success;
final _data = _yourModel.data;
Step 1 >
Creat BankDataModel.dart
class BankDataModel {
int? success;
int? totalResults;
List<Data>? data;
BankDataModel({this.success, this.totalResults, this.data});
BankDataModel.fromJson(Map<String, dynamic> json) {
success = json['success'];
totalResults = json['totalResults'];
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['success'] = this.success;
data['totalResults'] = this.totalResults;
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
int? id;
String? bankName;
String? bankLogo;
String? bankDesc;
String? rating;
Data({this.id, this.bankName, this.bankLogo, this.bankDesc, this.rating});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
bankName = json['bank_name'];
bankLogo = json['bank_logo'];
bankDesc = json['bank_desc'];
rating = json['rating'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['bank_name'] = this.bankName;
data['bank_logo'] = this.bankLogo;
data['bank_desc'] = this.bankDesc;
data['rating'] = this.rating;
return data;
}
}
Step 2>
Crete Object you want use
BankDataModel _bankDataModel = BankDataModel();
Step 3>
Api call
Future<BankDataModel> getData() async {
BankDataModel _bankDataModel = BankDataModel();
final url = 'your-url';
try {
final response = await client.get(url);
if (response.statusCode == 200) {
_bankDataModel = BankDataModel.fromJson(response.data); < -- Here Json to BankDataModel Convert..
print(_bankDataModel.totalResults.toString()); < -- here print 5 as per question.
return _bankDataModel;
} else {
print(response.statusCode);
throw response.statusCode;
}
} catch (error) {
print(error);
}
}
Thanks you. Happy to help you.

I'm trying to serialise the json receiving from api, but failing to do so

Whenever I'm trying to fetch data it's throwing exception:
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: The method 'map' was called on null.
Receiver: null
Tried calling: map<Location>(Closure: (dynamic) => Location))
print(responses) is printing null on console.
This is my function to get response from api:
String url1 = 'http://192.168.43.171:3000/location';
Future<void> showLocation() async {
var response = await http.get(Uri.encodeFull(url1));
if (response.statusCode == 200) {
print(response.body);
// Map<String, dynamic> parsedMap=jsonDecode(response.body);
final data = json.decode(response.body);
final responses = Details.fromJson(data[0]);
print(responses);
// print(parsedMap['location']);
} else {
throw Exception('failed to load');
}
}
This my locationModel.dart:
class Location {
final String latitude;
final String longitude;
Location({this.latitude, this.longitude});
factory Location.fromJson(Map<String, dynamic> parsedJson) {
return Location(
latitude: parsedJson['latitude'], longitude: parsedJson['longitude']);
}
}
class Details {
final String username;
final List<Location> locations;
Details({this.username, this.locations});
factory Details.fromJson(Map<String, dynamic> parsedJson) {
var list = parsedJson['locations'] as List;
print(list.runtimeType);
List<Location> locationList =
list.map((i) => Location.fromJson(i)).toList();
return Details(username: parsedJson['username'], locations: locationList);
}
}
My JSON:
[
{
"id":"ABC",
"username":"xyz",
"location":[
{
"latitude": "34",
"longitude": "343"
},
{
"latitude": "34",
"longitude": "32"
}
]
}
{
"id":"ABC1",
"username":"xyz1",
"location":[
{
"latitude": "34222",
"longitude": "32243"
},
]
}
]
You have a typo:
var list = parsedJson['locations'] as List;
vs
location:[
locations != location