I want to fetch data from a complex json API and display the data in a Flutter future builder.

This is the sample if json

 {
    "hours": [
        {
            "time": "2021-03-23T00:00:00+00:00",
            "waveHeight": {
                "icon": 1.35,
                "meteo": 1.25,
                "noaa": 1.28,
                "sg": 1.25
            }
        },
{
            "time": "2021-03-23T00:00:00+00:00",
            "waveHeight": {
                "icon": 1.35,
                "meteo": 1.25,
                "noaa": 1.28,
                "sg": 1.25
            }
        },
    ],
}

This is the function that fetch the data from the API

Future getJsonData() async {
    String url2 =
        'https://api.stormglass.io/v2/weather/point?lat=5.9774&lng=80.4288&params=waveHeight&start=2021-03-23&end2021-03-24';

    String apiKey =
        '0242ac130002-248f8380-7a54-11eb-8302-0242ac130002';
    print('0');

    Response response = await get(Uri.parse(url2),
        headers: {HttpHeaders.authorizationHeader: apiKey});

    final _extractedData = json.decode(response.body) as Map<String, dynamic>;

    List<Wave> _data = [];
    List<Wave> _fetchedData = [];

    _extractedData['hours'].forEach((value) {
      _fetchedData.add(Wave(
        time: value['time'],
        icon: value['icon'],
        meteo: value['meteo'],
        noaa: value['noaa'],
        sg: value['sg'],
      ));
    });

    _data = _fetchedData;

    print(_data);

    return _data;
  }

The data is printing in the console as below

/flutter ( 4879): [Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', Instance of 'Wave', In

Below is the futurebuilder

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("API"),
      ),
      body: Container(
        child: FutureBuilder(
            future: getJsonData(),
            builder: (context, AsyncSnapshot<dynamic> snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data[0]['time']);
              } else {
                return CircularProgressIndicator();
              }
            }),
      ),
    );
  }

When i run the app, the following error shows

The following NoSuchMethodError was thrown building FutureBuilder<dynamic>(dirty, state: _FutureBuilderState<dynamic>#e19f8):
Class 'Wave' has no instance method '[]'.
Receiver: Instance of 'Wave'
Tried calling: []("time")

The following is the wave class

class Wave {
  final String time;
  final double icon;
  final double meteo;
  final double noaa;
  final double sg;

  Wave({
    this.time,
    this.icon,
    this.meteo,
    this.noaa,
    this.sg,
  });

  factory Wave.fromJson(Map<String, dynamic> json) {
    return Wave(
        time: json['time'],
        icon: json['icon'],
        meteo: json['mateo'],
        noaa: json['noaa'],
        sg: json['sg']);
  }
}

I want to get the data and print it in a flutter listview


Solution 1: theCaptainXgod

This is because the data you returned from your getJsonData is not a map but a model class you created "WAVE".

Basically to access your "time" you need to change the code:

return Text(snapshot.data[0]['time']);

To

return Text(snapshot.data[0].time);