I'm trying to fetch both temperature and icon name from Openweathermap api. The problem occurs when I try to to fetch icon(or rather icon name).
It returns an error :
Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index' And I can't seem to find where the problem is. In other models I have other data types and it works fine, here it doesn't.
When I add icon to model, view returns null for temperature.
Here is code for weather model:
class WeatherData {
int? temp;
String? icon;
WeatherData({
this.temp,
this.icon
});
WeatherData.fromJson(dynamic json) {
var tempInKelvin = json["main"]["temp"];
temp = (tempInKelvin - 273.15).round();
icon = json["weather"]["icon"];
}
}
This is weather service:
class WeatherService {
final apiKey = "7e23369c183254302bda0471cc3f848c";
Future<WeatherData?> getWeatherForLocation(LocationData location) async {
WeatherData? weatherData;
var params = {
"lat": location.lat.toString(),
"lon": location.lon.toString(),
"city": location.city,
"appId": apiKey,
};
var url = Uri.http('api.openweathermap.org', '/data/2.5/weather', params);
Response response = await get(url);
if (response.statusCode == HttpStatus.ok) {
var jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
weatherData = WeatherData.fromJson(jsonResponse);
print("Request successful: $jsonResponse");
return weatherData;
} else {
print("Request failed with status: ${response.statusCode}");
return weatherData;
}
}
}
This is weather controller:
class WeatherController extends GetxController {
final WeatherService _weatherService = Get.find();
Rxn<LocationData> locationData = Rxn();
Rxn<WeatherData> weatherData = Rxn();
// RxString infoText = "...".obs;
String get address =>
"${locationData.value?.city},${locationData.value?.county}, ${locationData.value?.country}";
String get temperature => "${weatherData.value?.temp}";
// String get icon => "${weatherData.value?.icon}";
@override
void onInit() async {
super.onInit();
await getCurrentLocation();
await getTemperatureForCurrentLocation();
await getWeatherIcon();
}
getCurrentLocation() async {
LocationData? location = await _weatherService.getCurrentLocation();
print(location?.city);
locationData.value = location;
}
getTemperatureForCurrentLocation() async {
if (locationData.value != null) {
weatherData.value=
await _weatherService.getWeatherForLocation(locationData.value!);
// _getInfoText(weatherData.value?.temp);
}
}
}
CodePudding user response:
Looking at their API docs, it seems that weather
contains an array of objects (as a result, you need an integer index to figure out which one you want).
https://openweathermap.org/current
To fix it, you can simply opt to always use the first object in the weather array and take the icon/description from that:
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
Which is:
icon = json["weather"][0]["icon"];
CodePudding user response:
Can you please check this:
var tempInKelvin = double.parse(json["main"]["temp"]);
or this if your number is integer:
var tempInKelvin = int.parse(json["main"]["temp"]);