Reputation: 43
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
Upvotes: 0
Views: 1148
Reputation: 477
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);
}
Upvotes: 0
Reputation: 1
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();
}
}
}
Upvotes: 0