Minsaf
Minsaf

Reputation: 274

Parsing complex JSON with an array in flutter

I want to parse a complex JSON API that consists of an array and it shows the following error. The API has the details of weather and I want to display the time and wave height in the console.

The error

E/flutter ( 5675): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>'

E/flutter ( 5675): #0      _JsonDemoState.getJsonData
package:bottom_nav/APISample/JsonParsing.dart:25
E/flutter ( 5675): <asynchronous suspension>
E/flutter ( 5675):

This is the json which I need to parse.

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

THis is the function which parses the json

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

    String apiKey =
        'the API key';

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

    List data = jsonDecode(response.body);
    data.forEach((element) {
      Map obj = element;
      String hours = obj['hours'];
      Map wave = obj['waveHeight'];
      int icon = wave['icon'];
      print(icon);
    });
  }

Upvotes: 0

Views: 148

Answers (2)

glavigno
glavigno

Reputation: 503

JSON deserialization of response.body will return a Map not a List, hence an option is to access the value associated to the 'hours' key and cast it as a List of Map with key of type String and value of type dynamic.

final mapList = data['hours'] as List<Map<String, dynamic>>;
  
mapList.forEach((item) => print(item.values.last['icon']));
  

Upvotes: 1

Sam Chan
Sam Chan

Reputation: 1762

Would you mind to try this

 var jsonData = jsonDecode(response.body);
    List data = jsonData["hours"];

    data.forEach((element) {
      Map obj = element;
      Map wave = obj['waveHeight'];
      double icon = wave['icon'];
      print(icon);
    });

Upvotes: 1

Related Questions