How do you parse JSON that is inside an array - flutter

I am new to flutter development and is experimenting with how to use the flutter HTTP package 0.12.0+2.
If the response looks like this...
{
"coord": {
"lon": -76.8403,
"lat": 38.9649
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 93.47,
"feels_like": 99.34,
"temp_min": 88.84,
"temp_max": 97.74,
"pressure": 1017,
"humidity": 46
},
"visibility": 10000,
"wind": {
"speed": 1.99,
"deg": 304,
"gust": 1.99
},
"clouds": {
"all": 1
},
"dt": 1626462013,
"sys": {
"type": 2,
"id": 2030617,
"country": "US",
"sunrise": 1626429293,
"sunset": 1626481895
},
"timezone": -14400,
"id": 4369076,
"name": "Seabrook",
"cod": 200
}
Here is the code I have. Instead of printing all the data, how do I print only temp inside main
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude={part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data);
}

You can use:
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude={part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data['main']); //Will return [temp], [feels_like], [temp_min], etc..
print(data['main']['temp']); //Will return [93.47]
}

You can access the values of each fields by using the operator [$field] on the decoded json. Something like this:
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude=.{part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data['main']); // prints out { temp: 93.47, ...., humidity: 46 }
// what you want..
final mainTemp = data['main']['temp'];
print(mainTemp); // prints out 93.47.
print(data);
}
So, that's how you access the fields of of the decoded json-string response.
If you plan to use these received values throughout your app, consider changing the received response into an Interface which will provide you with more flexibility and also makes your code look cleaner.

Create Model Class here you can convert json to dart
https://javiercbk.github.io/json_to_dart/
Future<YourmodelName>getData() async {
YourmodelName data
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?
lat=38.964882&lon=-76.840271&exclude=
{part}&appid=b29e187fed23cf37dc160e6c115a270d');
if (response.statusCode == 200) {
data = YourmodelName.fromJson(response.data);;
print(data.main.temp);}
return data;
}

Related

Dart - Convert Map of objects fetched via HTTP REST-API

For my Calendar i get the following data as JSON from the Backend (*JAVA-Type = Map<LocalDate, List<Event>>):
{
"2022-05-28": [
{
"id": 2,
"title": "Multi day Event",
"fromDate": "2022-05-27T12:22:03.873569",
"toDate": "2022-05-28T11:22:03.873569",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "sozial"
}
],
"2022-05-27": [
{
"id": 2,
"title": "Multi day Event",
"fromDate": "2022-05-27T12:22:03.873569",
"toDate": "2022-05-28T11:22:03.873569",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "sozial"
},
{
"id": 1,
"title": "Testevent",
"fromDate": "2022-05-27T11:21:04.573754",
"toDate": "2022-05-27T12:21:04.573754",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "normal"
}
],
}
My Event Class looks like:
Class Event {
int id;
String title;
DateTime fromDate;
DateTime toDate;
Room room;
User user;
String eventType;
}
Now i need the same structure i had in the Backend (Map<DateTime, <List<Event>>) for my Calendar widget and i have no real clue on how to do it. I know how to convert json data into an object if i get a list of an object, but how can i store the date as key of the resulting map?
My code by now:
Future<Map<DateTime, List<Event>>> getEvents(DateTime _fromDate, DateTime
_endDate) async {
String _from = _fromDate.toString().split('.').first;
String _end = _endDate.toString().split('.').first;
final response = await get('${_url}calendar/events/$_from/$_end',
headers: {HttpHeaders.authorizationHeader: 'Bearer $_bearer'});
if (response.status.hasError) {
return Future.error('${response.statusText}');
} else {
final parsed = jsonDecode(response.body);
return parsed;
}
}
You need to do something like that:
var json = {...}; // <-- json obj
// method to parse data to map with list Event
dynamic fromJson(Map<String, dynamic> json){
var map = new Map();
json.keys.forEach((key){
// key is the date
map[key] = json[key].map((e) => Event.fromJson(e)).toList(); // <- need to create a method fromJson in your Event class
});
return map;
}
(...)
class Event {
int id;
String title;
DateTime fromDate;
DateTime toDate;
Room room;
User user;
String eventType;
fromJson(Map<String, dynamic> json) => Event(...); // <- parse json to Event class
}

How to set and get data using SharedPreferences?

Previously i do SharedPreferences to get user name. That was okay.
from API Response
"status": 200,
"message": "Login Successfully",
"result": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9mYzBhLTIwMi0xODctMy01Lm5ncm9rLmlvXC9hcGlcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNjM5OTAxMDQ0LCJleHAiOjE2Mzk5ODc0NDQsIm5iZiI6MTYzOTkwMTA0NCwianRpIjoidndLWHlOYlJmTXdzMlFZbCIsInN1YiI6MiwicHJ2IjoiODdlMGFmMWVmOWZkMTU4MTJmZGVjOTcxNTNhMTRlMGIwNDc1NDZhYSJ9.Tr_CTZeKX6M2pycRal7CGeQ0i3FA3Fco0Xm5dwtWwDA",
"user": {
"id": 2,
"name": "hani",
Set and get
if (res.statusCode == 200) {
setState(() {
message = "Login Success";
});
print(res.body);
SharedPreferences localStorage = await SharedPreferences.getInstance();
localStorage.setString('user', json.encode(body['result']['user']));
String name;
_loadUserData() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var user = jsonDecode(localStorage.getString('user'));
if (user != null) {
setState(() {
name = user['name'];
});
}
}
But if i want to get the id from this API Response, what should i write?
to set and get that id using SharedPreferences.
Or there's another way to get that id?
"status": "success",
"result": [
{
"id": 1,
"exercise_name": "Reading Set 1",
"exercise_type_id": 1,
"show": 1,
"finalized": 1,
"created_at": "2021-12-17T07:13:50.000000Z",
"updated_at": "2021-12-17T20:47:57.000000Z",
"total": 0
},
{
"id": 3,
"exercise_name": "Reading Set 2",
"exercise_type_id": 1,
"show": 1,
"finalized": 1,
"created_at": "2021-12-17T20:34:50.000000Z",
"updated_at": "2021-12-17T20:46:15.000000Z",
"total": 0
}
]
Sorry, I new to coding and flutter.
Hope someone can help
In the first response result is a JSONObject but in the second one it is JSONArray.
if (res.statusCode == 200) {
//do what ever you want
final data = jsonDecode(response.body) as Map<String, dynamic>;
for (var exercise in data['result']) {
//Now you can access each item
if(exercise['exercise_name']== 'Reading Set 1'){
//Store ID in SharedPrefrence
}
}
}

Flutter API Call using http

I'm trying to get json data from Api by using the following
Future<SubjectList> getsubjectList(
String userId, String accountId) async {
final response = await http
.get(Uri.https(_baseUrl, 'v1/package/subject-details'), headers: {
'Content-Type': 'application/json',
'user-id': userId,
'account-id': accountId,
});
SubjectList jsonresponse = json.decode(response.body); //'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'SubjectList'
print('This is response =$jsonresponse');
return jsonresponse;
}
I have modelled the object as follows
class SubjectList {
SubjectList({
this.subject,
this.score,
this.progress,
});
String? subject;
double? score;
String? progress;
factory SubjectList.fromMap(Map<String, dynamic> json) => SubjectList(
subject: json["subject"],
score: json["score"].toDouble(),
progress: json["progress"],
);
Map<String, dynamic> toJson() => {
"subject": subject,
"score": score,
"progress": progress,
};
}
The Data is as follows
{
"success": true,
"data": [
{
"subject": "Grammar",
"score": 57.17,
"progress": "96.77%"
},
{
"subject": "Maths",
"score": 52.12,
"progress": "73.08%"
},
{
"subject": "EVS",
"score": 55.75,
"progress": "97.96%"
},
{
"subject": "Social Studies",
"score": -1,
"progress": "-1%"
},
{
"subject": "Hindi",
"score": 51.36,
"progress": "60.87%"
},
{
"subject": "Vocabulary",
"score": 62.55,
"progress": "68.12%"
},
]
When ever i try to access using the model i'm receiving the error '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'SubjectList'. How do I get the data properly ?
Change this line
SubjectList jsonresponse = json.decode(response.body);
to something like
List<SubjectList> list = json.decode(response.body)['data'].map((d) => SubjectList.fromMap()).toList();
You can create a class for the response itself and the do the fromMap on it.

How to pass a list of json to body of http Post request in Flutter?

I have objects that will filled by a user in a form. I parse these objects to json and add that json in a list to pass in body of request. But i cant do this.
submitQuestions() async {
var headers = {
'Content-Type': 'application/json',
'x-auth-token': '123edrfe33ewed'
};
var request = http.Request('POST', Uri.parse('url'));
request.body = json.encode({
"school_id": "123",
"teacher_id": "123",
"observer_id": "123",
"subject_id": "123",
"subject_name": "abc",
"class_id": "123",
"batch_id": "123",
"topic": "topic",
"academic_year": "2019-2020",
"remarks_data": [
{
"_id": "123",
"heading": "heading",
"Indicators": [
{
"name": "abc",
"_id": "123",
"remark": "abc",
"point": 4
},
{
"name": "abc",
"_id": "123",
"remark": "abc",
"point": 1
}
]
},
{
"_id": "123",
"heading": "abc",
"Indicators": [
{
"name": "abc",
"_id": "123",
"remark": "abc",
"point": 3
}
]
}
]
});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
}
This json will change dynamically when the number of questions increase. I cannot place this json file in the body like this. How to Do this one.
Wrap each list of json with jsonEncode
like:
"remarks_data": jsonEncode(..)
and do not forget to import.
import 'dart:convert';
The request body try to use Map data type. You can create a model class to deal with it.
Example
class School {
String school_id;
String teacher_id;
String observer_id;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['school_id'] = this.school_id;
data['teacher_id'] = this.teacher_id;
data['observer_id'] = this.observer_id;
...
return data;
}
}
/// Make sure your _school got data
School _school;
request.body = _school.toJson();

Flutter return array from response from server

in this part of my code await webApi.getKeywords(); return array which that can get from server, now when i try to return that i get error:
type 'List<dynamic>' is not a subtype of type 'String'
get data from server code:
Future<List<KeywordsResponse>> _getKeywords(BuildContext context) async {
try {
final webApi = Provider.of<WebApi>(context);
final response = await webApi.getKeywords();
List<KeywordsResponse> list = List();
if (response.statusCode == 200) {
list = (json.decode(response.body) as List)
.map((data) => new KeywordsResponse.fromJson(data))
.toList();
return list;
} else {
throw Exception('Failed to load photos');
}
} catch (error) {
print(error);
return null;
}
}
KeywordsResponse class:
#JsonSerializable(nullable: true)
class KeywordsResponse{
#JsonKey(name:'id')
final int id;
#JsonKey(name:'title')
final String title;
#JsonKey(name:'description')
final String description;
KeywordsResponse(this.id, this.title, this.description);
factory KeywordsResponse.fromJson(Map<String, dynamic> json) => _$KeywordsResponseFromJson(json);
Map<String, dynamic> toJson() => _$KeywordsResponseToJson(this);
}
return of response.body:
[
{
"id": 1,
"user_id": 1,
"title": "asdasdasd",
"description": "asdasdasd",
"type": "post",
"slug": "asdasdad",
"featured_images": {
"images": {
"300": "/uploads/post_images/2019/300_1573573784.png",
"600": "/uploads/post_images/2019/600_1573573784.png",
"900": "/uploads/post_images/2019/900_1573573784.png",
"original": "/uploads/post_images/2019/1573573784.png"
},
"thumbnail": "/uploads/post_images/2019/300_1573573784.png"
},
"lang": "fa",
"visit": 0,
"categories": [
{
"id": 1,
"title": "aaaaaaa",
"lang": "fa",
"parent": 0,
"pivot": {
"contents_id": 1,
"content_categories_id": 1
}
}
]
},
{
"id": 2,
"user_id": 1,
"title": "asdasdasd",
"description": "asdadasd",
"type": "post",
"slug": "asdasdasda",
"featured_images": {
"images": {
"300": "/uploads/post_images/2019/300_1573573846.png",
"600": "/uploads/post_images/2019/600_1573573846.png",
"900": "/uploads/post_images/2019/900_1573573846.png",
"original": "/uploads/post_images/2019/1573573846.png"
},
"thumbnail": "/uploads/post_images/2019/300_1573573846.png"
},
"lang": "fa",
"visit": 0,
"categories": [
{
"id": 2,
"title": "bbbbbbbb",
"lang": "fa",
"parent": 0,
"pivot": {
"contents_id": 2,
"content_categories_id": 2
}
}
]
}
]
problem is on this line of code:
json.decode(response.body)
Try this:
list = List<KeywordsResponse>.from(response.body.map((x) => KeywordsResponse.fromJson(x)));