Flutter - The best way to parse a JSON
Compare this with things like quicktype: (1) If you do not have a model class, then try to use things like quicktype to get that class from a sample json string. (2) However, I suggest not to use the toJson
and fromJson
given by quicktype. The reason is that, when your model changes (say add a field / change a field), you must also change your toJson/fromJson accordingly (which is time-consuming and error-prone). Otherwise you get a bug.
If you already have your model class and only need the toJson
and fromJson
methods: Then the very famous json_serializable package suits you. It will happily generate the toJson
and fromJson
.
For example, say you have
class Person {
final String firstName;
final String lastName;
final DateTime dateOfBirth;
}
Then with a bit of boilerplate code, it will auto give you
Person _$PersonFromJson(Map<String, dynamic> json) {
return Person(
firstName: json['firstName'] as String,
lastName: json['lastName'] as String,
dateOfBirth: DateTime.parse(json['dateOfBirth'] as String),
);
}
Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
'firstName': instance.firstName,
'lastName': instance.lastName,
'dateOfBirth': instance.dateOfBirth.toIso8601String(),
};
Actually that package is more powerful than that. Check out the link for more details.
How to parse any json file in Dart?
Using the dart_convert library you can parse a json string to a map using Map<String, dynamic> yourMap = jsonDecode(jsonString);
Parsing JSON in Dart
The documentation is correct.
//if JSON is an array (starts with '[' )
List<Map> x = JSON.decode(responseText);
print(x[0]['title']);
//if JSON is not an array (starts with '{' )
Map z = JSON.decode(responseText);
print(z['content']);
print(z['id']);
print(z['title']);
Flutter how to parse JSON data
First thing the response from API is not a json list, its a simple json object.
If you wanna iterate over the keys of the above object you can create a list with all the keys and then use key index to get the actual key name in the response.
final List<String> keys = ["alm","co2","hu","temp","th","tm","ts"];
then you can modify your body widget like following -
body: new ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
return new ListTile(
leading: const Icon(Icons.stay_primary_portrait),
title: Text(data.length.toString()),
subtitle: Text(data[keys[index]]),
trailing: Icon(Icons.more_vert),
dense: true,
isThreeLine: true,
);
},
),
Hope this helps!
How to parse complex JSON using default methods in Flutter?
To work with JSON objects that have deep/multiple levels/recursive dot notation, then you can use a fantastic Dart package: g_json. I find it super easy and simple!
It doesn't use generated code as on Flutter recommended packages for JSON and these are complicated. Dart & Flutter teams have to improve.
I use a complex JSON object and your example and I show you how I access the data (you have to clean your JSON string, maybe your example is copied from a place that add extra double quotes " "
on brackets).
Now, look at my code:
import 'dart:convert';
import 'package:g_json/g_json.dart';
void main() {
String jsonSimple = '{"a":"1"}';
// Get value from only one level JSON object.
final Map<String, dynamic> resultSimple = json.decode(jsonSimple);
print(resultSimple);
// Your example with some cleaning.
String jsonExample = jsonEncode({
"a": {"b": 7}
});
var resultDeep = JSON.parse(jsonExample);
print(resultDeep['a']['b'].rawString());
// Deep JSON object
// This is a real JSON data from api.openweathermap.org/data/2.5/weather?q=Barcelona&appid=<your_api_key>. You can try it on your browser, put it on the url and press `ENTER`.
String jsonWeather = jsonEncode({
"coord": {"lon": 2.159, "lat": 41.3888},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"base": "stations",
"main": {
"temp": 291.21,
"feels_like": 291.11,
"temp_min": 289.53,
"temp_max": 293.62,
"pressure": 1016,
"humidity": 78
},
"visibility": 10000,
"wind": {"speed": 0.45, "deg": 212, "gust": 1.79},
"clouds": {"all": 75},
"dt": 1633360018,
"sys": {
"type": 2,
"id": 18549,
"country": "ES",
"sunrise": 1633326668,
"sunset": 1633368526
},
"timezone": 7200,
"id": 3128760,
"name": "Barcelona",
"cod": 200
});
print(jsonWeather);
// It prints: `String`
print(jsonWeather.runtimeType);
resultDeep = JSON.parse(jsonWeather);
print(resultDeep['wind']['speed'].rawString());
print(resultDeep['weather'][0]['main'].rawString());
// Extract data for each item of the array.
final List<dynamic> listJsonWeather = resultDeep['weather'].value;
List<WeatherEntity> listWeathers = [];
for (dynamic jsonWeather in listJsonWeather) {
listWeathers.add(WeatherEntity(
id: jsonWeather['id'].toString(),
title: jsonWeather['main'] as String,
overview: jsonWeather['description'] as String,
image: '<url>/${jsonWeather['icon']}',
));
}
}
The console prints the next outcome:
7
String
0.45
"Clouds"
Tips
You can use Postman to fetch API data from services. A very useful tool, trust me!
Related Topics
What Does The Shrink-To-Fit Viewport Meta Attribute Do
Gradient Colors in Internet Explorer
How to Get Rid of X and Up/Down Arrow Elements of a Input Date
<H1>, <H2>, <H3>... Tags, Inline Within Paragraphs (<P>)
Create Tree View with Horizontal and Vertical Lines Showing The Connectivity Using CSS
Yet Another Divs Vs Tables Issue: Forms
How to Get a Flexbox to Have a Center Fixed and a Bottom Fixed Children Together
Making a Flex Item Float Right
@Media Queries and Image Swapping
Subpixel Anti-Aliased Text on HTML5's Canvas Element
How to Replace Radio Buttons with Images
HTML5 Standards of Nesting Div in Li or Dl
Has Anyone Gotten HTML Emails Working with Twitter Bootstrap