简体   繁体   English

如何在 Dart\Flutter 中使用我的 JSON 响应

[英]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.我是 flutter 的新手,并按照一个小教程从简单的 Json 中获取 Json 响应。 Now I want to get my weather data from a more complex API.现在我想从更复杂的 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.这是我在 Kotlin 中制作的一个项目,效果很好,我只想看看它在 Flutter 中的情况,但是我在将响应转换为 class 时遇到了一些问题。 (sorry if my terminology isn't quite right). (对不起,如果我的术语不太正确)。

My json method is this:我的 json 方法是这样的:

  _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:我的 API 响应类似于:

{"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起初我想做一些简单的事情,比如'final weathersJSON = json.decode(response.body);',但我收到了这个错误

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable'未处理的异常:类型“_InternalLinkedHashMap<String, dynamic>”不是“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.因此,我根据另一个堆栈问题添加了 Map,因为它显然有助于 Json 末尾的天气列表位,并且错误消失了。

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.我想将所有 API 信息添加到 class 中,以便在应用程序的其他地方使用。 I made a list of type WeatherData called _weatherDatas.我制作了一个名为 _weatherDatas 的 WeatherData 类型列表。 The latest error I'm dealing with is我正在处理的最新错误是

Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.未处理的异常:NoSuchMethodError:在 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干杯: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!看看这个很棒的工具,它可以让您轻松地将 json 转换为 Dart 类 PS:它支持对象嵌套! XD XD

Hope my answer helps!希望我的回答有帮助!

In your model在你的 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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