Home > Mobile >  Flutter Exception Handling Show error message when the user enteres incorrect city name
Flutter Exception Handling Show error message when the user enteres incorrect city name

Time:11-07

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();
}
  • Related