_TypeError (type 'Null' is not a subtype of type 'FutureOr<Stations>')

Issue

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()
}

Solution

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 enter image description here

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:

First option,

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.

Second option,

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; 
}

Answered By – Michael Soliman

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *