Have recently installed Flutter null safety
and having fixed most of the code I am having trouble with an API call.
It returns _TypeError (type 'Null' is not a subtype of type 'FutureOr<Stations>')
I haven't found a SO answer that seems to line up with my issue/ code method.
This is the button click that calls the API from main.dart
void _anchoredMapMarkersButtonClicked() {
_mapMarkerExample.showAnchoredMapMarkers();
}
And this is the API call itself with error displaying at the bottom } catch(Exception) {
line
Future<Stations> fetchStations() async {
var client = http.Client();
var stations;
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var lat = position.latitude;
var long = position.longitude;
try{
var response = await client.get(Uri.parse('https call'));
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
stations = Stations.fromJson(jsonMap);
//print(stations);
}
} catch(Exception) {
return stations;
}
return stations;
}
Updated Code
Future<Stations> fetchStations() async {
var client = http.Client();
Stations? stations;
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
print(position);
var lat = position.latitude;
var long = position.longitude;
try{
var response = await client.get(Uri.parse('https://transit.hereapi.com/v8/stations?in=$lat,$long&return=transport&apiKey=uIioesb_EbnEXgPHlH0Z5e7gPGy9irpq2dRJcjuYPZY'));
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
//print(jsonMap);
inspect(jsonMap);
stations = Stations.fromJson(jsonMap);
//print(stations);
}
} catch(Exception) {
Future<Stations?> fetchStations()
}
Future<Stations?> fetchStations()
}
when you enable null safety, each type is divided into nullable and non-nullable type, as shown in the following picture, from dart official docs Non-nullable and nullable types
So when you declare var stations
, by default it have the value dynamic
, which -in dart null safety- can be null, but the return of the function is of type Future<Stations>
, in which the value of the future Stations
can never be null (because it doesn't have the ? after the type),To solve this, you have to options:
declare your stations variable like this
Stations? stations; // you tell the compiler that this variable can hold null value
and then make the return of the function
Future<Stations?> fetchStations()
this way it's valid that you return null from the function.
is declaring stations as non null like this
Stations stations; // this will give a compiler error
but now you'll have a compiler error that stations is a non null type and you didn't it assign it any value, you can either assign an initial value to it
Stations stations = Stations();
Or, use the late
keyword,
late Stations stations; // tell the compiler that this is non null object that i'll assign a value to later
but notice that in the latter, you have to assign stations
a value at some point, if you don't you'll get an exception.
if you chose the first option, the function should look like the following,
Future<Stations?> fetchStations() async {
var client = http.Client();
Stations? stations;
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var lat = position.latitude;
var long = position.longitude;
try{
var response = await client.get(Uri.parse('https call'));
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
stations = Stations.fromJson(jsonMap);
//print(stations);
}
} catch(e) {
// you don't need to return stations, because you return it at the end of the function
// return stations;
print("Exception Happened: ${e.toString()}")
}
// you can return a nullable object because the function return type is a nullable type
return stations;
}