Reputation: 139
I'm writing a flutter method in which I want to parse a simple JSON data
{"alm":3,"co2":1,"hu":2,"temp":32,"th":11,"tm":31,"ts":41}
I tried to parse it in a simple get class
List data;
Future<String> getData() async {
http.Response response = await http.get(
Uri.encodeFull("http://chicken20.pythonanywhere.com/jsonn"),
headers: {"Accept": "application/json"});
print(response.body);
data = json.decode(response.body);
print(data);
return "Success!";
and this how I tried to use in material app
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('${_deviceData}'),
trailing: Icon(Icons.more_vert),
dense: true,
isThreeLine: true,
);
},
),
and I got this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>'
and nothing was shown in the screen
Upvotes: 1
Views: 1012
Reputation: 2270
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!
Upvotes: 1
Reputation: 7670
You're getting a Map
from your API. you cannot use that on a ListView.builder
. You can use a regular ListView
and add the ListTiles manually.
Create the ListView
and add the ListTiles manually using each key in the map.
body: ListView(
children: <Widget>[
buildTile('alm'),
buildTile('co2'),
buildTile('hu'),
buildTile('temp'), // continue this for others
],
),
Create the ListTile
to be used in the ListView
buildTile(String key){
return ListTile(
leading: const Icon(Icons.stay_primary_portrait),
title: Text('$key'),
subtitle: Text('${data['$key']}'),
trailing: Icon(Icons.more_vert),
dense: true,
isThreeLine: true,
);
}
Upvotes: 0