0
votes

I'm getting the error messages:

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Future <dynamic>`
_LocationScreenState.build.<anonymous closure> 
(package:clima/screens/location_screen.dart:71:32) 
<asynchronous suspension>

The line being pinpointed is inside this:

FlatButton(
   onPressed: () async {
     var weatherData = await weather.getLocationWeather();
     updateUI(weatherData); //<==it's this line
                    },

weather.getLocationWeather() returns a variable of type Future<dynamic>. It's JSON and, evaluating it in the debugger, it's the expected JSON. The upDateUI() method begins

  void updateUI(Future<dynamic> weatherDataFuture) async {
    final weatherData = await weatherDataFuture;

and then goes on to parse the resulting weatherData. It's called earlier in the program and works as expected. I'm sure the issue is connected to my never ending but still continuing battle to understand asynchronous programming :-)

3
The weather.getLocationWeather() value is "_InternalLinkedHashMap<String, dynamic>" and seem "updateUI(Future)" returns the same that "weather.getLocationWeather()" - Norberto Martín Afonso
@NorbertoMartínAfonso -- Thanks for responding! I am not sure I understand totally. I understand weather.getLocationWeather() apparently returns type "_InternalLinkedHashMap<String,dynamic>". But updateUI() is void; it does not return anything(?). - Al C
Try my answer I was edited and returns map values - Norberto Martín Afonso

3 Answers

2
votes

The await weather.getLocationWeather() gets the future returned by getLocationWeather and waits for it to complete to a value. That value is a map.

You then call updateUI with that map value, even though it expects a futuure. The variable is typed as dynamic, so you get no static warnings, just a run-time error.

   onPressed: () async {
     var weatherData = await weather.getLocationWeather();
     updateUI(weatherData); //<==it's this line

Try removing the await. Then weatherData will be a Future<dynamic>, which is exactly the type expected by updateUI. (You can then also remove the async from the function).

0
votes

Try this:

final weatherData;
Future<Map<String, dynamic>> weatherDataFuture async{
  return weather.getLocationWeather();
}

FlatButton(
  onPressed: () {
  weatherDataFuture.then((value){
   weatherData=value.values;
 });
} 
) 
0
votes

The return value from getting the data needs to be casted. I’d recommend looking into the JSON tutorials in the flutter documentation.

    FlatButton(
       onPressed: () async {
         var weatherData = Map<String, dynamic>.from(await weather.getLocationWeather());
         updateUI(weatherData); //<==it's this line
    },
void updateUI(Map<String, dynamic> weatherData) async {
    ...

===== edit based on comments =====

FlatButton(
    onPressed: () async {
      var weatherData = SynchronousFuture(Map<String, dynamic>.from(await weather.getLocationWeather()));
      updateUI(weatherData); //<==it's this line
},
void updateUI(Future<Map<String, dynamic>> weatherData) async {
    ...