Mohamed Borhene Hamedi
Mohamed Borhene Hamedi

Reputation: 139

Flutter how to parse JSON data

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

Answers (3)

Tanuj
Tanuj

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

JideGuru
JideGuru

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

ARAB KUMAR
ARAB KUMAR

Reputation: 96

Your Url hai double 'n' in json. are you sure about that?

Upvotes: 0

Related Questions