I am using one of openweathermap to get the latitude and longitude based on a city name. Whenever the user enters an invalid city name, this is the response from the api.
How can I catch this and show an error message to the user.
This is the function that makes the api call.
Constants myConstaints = Constants();
Future<CityInfo> gettingCityData(String cityName) async {
var url = Uri.parse(
'https://api.openweathermap.org/geo/1.0/direct?q=$cityName&limit=1&appid=${myConstaints.apiKey}');
var response = await http.get(url);
if (response.statusCode == 200) {
var i = CityInfo.fromJson(jsonDecode(response.body));
return i;
} else
throw Exception('error');
}
CityInfo class and its constructor
class CityInfo {
String name;
double lat;
double long;
CityInfo.fromJson(List<dynamic> json)
: name = json[0]['name'],
lat = json[0]['lat'].toDouble(),
long = json[0]['lon'].toDouble();
}
Provider
Future<void> cityName(String cityName) async {
cityInfo = await gettingCityData(cityName);
notifyListeners();
}
CodePudding user response:
The API is returning a list of cities. It may return an empty list.
First of all, the CityInfo.fromJson should not take a list as input. It should rather only focus on converting a CityInfo JSON object to a CityInfo object.
class CityInfo {
String name;
double lat;
double long;
CityInfo.fromJson(Map<String, dynamic> json)
: name = json['name'],
lat = json['lat'].toDouble(),
long = json['lon'].toDouble();
}
Now, notice how CityInfo can be null so your future should return a nullable CityInfo
Future<CityInfo?> gettingCityData(String cityName)
Now to handle the request,
Future<CityInfo?> gettingCityData(String cityName) async {
final url = Uri.parse(
'https://api.openweathermap.org/geo/1.0/direct?q=$cityName&limit=1&appid=${myConstaints.apiKey}');
final response = await http.get(url);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
if (data.isEmpty) return null; // List is empty.
final cityJson = data.first as Map<String, dynamic>;
return CityInfo.fromJson(cityJson);
} else
throw Exception('Error');
}
}
Now, the method can be called as,
Future<void> cityName(String cityName) async {
cityInfo = await gettingCityData(cityName);
if (cityInfo == null) {
// City was not found. Show some message here.
}
notifyListeners();
}