简体   繁体   中英

How to use my JSON response in Dart\Flutter

I'm new to flutter, and followed a little tutorial for getting a Json response from a simple Json. Now I want to get my weather data from a more complex API. This is a project I made in Kotlin which works great, and I just want to see how it's like in Flutter, but I'm having some issues turning the response into a class. (sorry if my terminology isn't quite right).

My json method is this:

  _loadData() async {
    String weatherURL = "https://api.openweathermap.org/data/2.5/onecall?lat=33.441792&lon=-94.037689&exclude=hourly,daily,minutely&appid=myapikey";
    http.Response response = await http.get(weatherURL);
    setState(() {
        final Map<String, dynamic> weathersJSON = json.decode(response.body);
        log(weathersJSON.toString());
        List<dynamic> data = weathersJSON[WeatherData];
        print(data[0]["lat"]);

      for(var weatherJSON in weathersJSON) {
        final weatherData = WeatherData(weatherJSON["lat"], weatherJSON["lon"], weatherJSON["timezone"], weatherJSON["timezone_offset"], weatherJSON["current"]);
        _weatherDatas.add(weatherData);
      }
    });
  }

And my API response is something like:

{"lat":33.44,
 "lon":-94.04,
 "timezone":"America/Chicago",
 "timezone_offset":-18000,
 "current":
    {"dt":1594400068,
    "sunrise":1594379674,
    "sunset":1594430893,
    "temp":303.95,
    "feels_like":306.84,
    "pressure":1018,
    "humidity":62,
    "dew_point":295.83,
    "uvi":11.81,
    "clouds":20,
    "visibility":16093,
    "wind_speed":3.1,
    "wind_deg":260,
    "weather":[
      {"id":801,
      "main":"Clouds",
      "description":"few clouds",
      "icon":"02d"}
      ]
     }
 }

At first I wanted to do something simple like 'final weathersJSON = json.decode(response.body);', but I was getting this error

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable'

So I added the Map based on another Stack question because it apparently helps the Weather list bit at the end of the Json, and the error goes away.

However now I'm just a little stuck. I want to add all of that API info into a class to be used elsewhere in the app. I made a list of type WeatherData called _weatherDatas. The latest error I'm dealing with is

Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.

I would really really appreciate any advice you have.

Also here's my data classes:

class WeatherData {
  final double lat;
  final double lon;
  final String timezone;
  final int timezone_offset;
  final Current current;

  WeatherData(this.lat, this.lon, this.timezone, this.timezone_offset, this.current);
}

class Weather {
  final int id;
  final String main;
  final String description;
  final String icon;

  Weather(this.id, this.main, this.description, this.icon);
}

class Current {
  final int dt;
  final int sunrise;
  final int sunset;
  final double temp;
  final double feels_like;
  final int pressure;
  final int humidity;
  final double dew_point;
  final double uvi;
  final int clouds;
  final int visibility;
  final double wind_speed;
  final int wind_deg;
  final List<Weather> weather;

  Current(this.dt, this.sunrise, this.sunset, this.temp, this.feels_like, this.pressure, this.humidity,
      this.dew_point, this.uvi, this.clouds, this.visibility, this.wind_speed, this.wind_deg, this.weather);
}

CHEERS:D

for the list you need to do like this

    class Current {
  final int dt;
  final int sunrise;
  final int sunset;
  final double temp;
  final double feels_like;
  final int pressure;
  final int humidity;
  final double dew_point;
  final double uvi;
  final int clouds;
  final int visibility;
  final double wind_speed;
  final int wind_deg;
  final List<Weather> weather;

  Current(
      this.dt,
      this.sunrise,
      this.sunset,
      this.temp,
      this.feels_like,
      this.pressure,
      this.humidity,
      this.dew_point,
      this.uvi,
      this.clouds,
      this.visibility,
      this.wind_speed,
      this.wind_deg,
      this.weather);

  Current.parseJson(Map<String, dynamic> json) {
    this.dt = json['dt'];
    ...
    //for parsing weather list
    if (json['weather'] != null) {
        var weatherJson = json['weather'] as List<dynamic>;
        weather = weatherJson
            .map((tempJson) => Weather.parseJson(tempJson)) //in weather class you need to write  parseJson
            .toList();
      }
  }
}

Check out this awesome tool that allows you to easily convert your json to Dart classes PS: It supports objects nesting! XD

Hope my answer helps!

In your model

 import 'package:recrearte/model/user.dart';
    class WeatherData {
final double lat;

  final double lon;
  final String timezone;
  final int timezone_offset;
  final Current current;

  WeatherData(
      {this.lat,
      this.lon,
      this.timezone,
      this.timezone_offset,
      this.current,
     });

  factory WeatherData.fromJson(Map<String, dynamic> json) {
    return new WeatherData(
        lat: json["lat"],
        current: json.containsKey('current') ? User.fromJson(json['current']) : null,
        timezone_offset: json["timezone_offset"] ?? 0,
        timezone: json["timezone"] ?? "",
        lon: json["lon"] ?? "",
        );
  }

  Map<String, dynamic> toJson() => {
        "lat": lat ?? "",
        "current": this.current != null ? this.current.toJson() : null,
        "timezone_offset": timezone_offset ?? 0,
        "timezone": timezone ?? "",
        "lon": lon ?? "",
      };
}

In service

_loadData() async {
    String weatherURL = "https://api.openweathermap.org/data/2.5/onecall?lat=33.441792&lon=-94.037689&exclude=hourly,daily,minutely&appid=myapikey";
    http.Response response = await http.get(weatherURL);
    setState(() {

        var json2 = json.decode(response.body);
        return decode(json2);
    });
  }


  WeatherData decode(dynamic element) {
  return WeatherData.fromJson(element);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM