'Instance of 'Future<dynamic>' flutter problem?
In order to get the 5 forecast weather day using OpenWeatherMAP API, I created the following function :
Future fetchForecastDay() async{
Location located = Location();
await located.getLocation();
NetworkHelper networkhelper =
NetworkHelper('https://api.openweathermap.org/data/2.5/forecast?lat=${located.lattitude}&lon=${located.longitude}&appid=$apiKey&units=metric');
var weatherdata = await networkhelper.getData();
return weatherdata;
}
fetchForecastDay is written is WeatherModel class as bellow :
import '../services/location.dart';
import '../services/networking.dart';
const apiKey = 'd8cdd9eca073d9bbf5ef49405cbf50e8';
const openWeatherMapURL = 'https://api.openweathermap.org/data/2.5/weather';
class WeatherModel {
Future<dynamic> getCityWeather(String cityName) async{
NetworkHelper networkhelper = NetworkHelper(
'$openWeatherMapURL?q=$cityName&appid=$apiKey&units=metric'
);
var weathercitydata = await networkhelper.getData();
return weathercitydata;
}
Future<dynamic> getLocationWeather() async{
Location located = Location();
await located.getLocation();
NetworkHelper networkhelper =
NetworkHelper(
'$openWeatherMapURL?lat=${located.lattitude}&lon=${located.longitude}&appid=$apiKey&units=metric');
var weatherdata = await networkhelper.getData();
return weatherdata;
}
///////////////////////////////////////////////////////////////////////
///
///
Future fetchForecastDay() async{
Location located = Location();
await located.getLocation();
NetworkHelper networkhelper =
NetworkHelper('https://api.openweathermap.org/data/2.5/forecast?lat=${located.lattitude}&lon=${located.longitude}&appid=$apiKey&units=metric');
var weatherdata = await networkhelper.getData();
return weatherdata;
}
}
MY Get request is depending on the (Attitude and Longitude) found on the getLocation function. getLocation() function is written in another file as bellow :
import 'package:geolocator/geolocator.dart';
class Location {
double? longitude;
double? lattitude;
Future<void> getLocation() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
lattitude = position.latitude;
longitude = position.longitude;
}
}
when I tried to print fetchForecastDay() data in the LocationScreen file:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../services/weather.dart';
import '../utilities/constants.dart';
import '../screens/city_screen.dart';
class LocationScreen extends StatefulWidget {
//var locationWeather;
//LocationScreen({this.locationWeather});
static const routeName = '/location-screen';
@override
_LocationScreenState createState() => _LocationScreenState();
}
class _LocationScreenState extends State<LocationScreen> {
WeatherModel weathertype = WeatherModel();
int? temperature;
String? weatherIcon;
String? cityName;
String? weatherMessage;
String? weatherState;
List<int>? maxtemp = List.filled(7, 0);
List<int>? mintemp = List.filled(7, 0);
/* @override
void intiState(){
// var weatherData = ModalRoute.of(context)!.settings.arguments as dynamic;
super.initState();
print(widget.locationWeather);
}
*/
@override
void didChangeDependencies() {
super.didChangeDependencies();
var weatherData = ModalRoute.of(context)!.settings.arguments as dynamic;
updateUi(weatherData);
print(weathertype.fetchForecastDay());
}
void updateUi(dynamic weatherData){
try {
setState(() {
if (weatherData == null) {
temperature = 0;
weatherIcon = 'Error';
weatherMessage = 'Unable to get weather data';
cityName = '';
return;
}
double? temp = weatherData['main']['temp'];
temperature = temp!.toInt();
weatherMessage = weathertype.getMessage(temperature!).toString();
var condition = weatherData['weather'][0]['id'];
weatherIcon = weathertype.getWeatherIcon(condition);
cityName = weatherData['name'];
weatherState = weatherData['weather'][0]['main'];
});
} catch (e) {
print('An error has occured, please try again');
}
}
@override
Widget build(BuildContext context) {
print(weathertype.fetchForecastDay());
return Scaffold(
body: Container(
decoration: BoxDecoration(
image:DecorationImage(
image: AssetImage('images/sky.jpg'),
fit: BoxFit.cover,
// colorFilter: ColorFilter.mode(
// Colors.white.withOpacity(0.8), BlendMode.dstATop),
),
),
constraints: BoxConstraints.expand(),
child: SafeArea(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
style: ButtonStyle(
),
onPressed: (){
var weatherdata = weathertype.getLocationWeather();
updateUi(weatherdata);
},
child: Icon(
Icons.near_me,
size: 40,
),
),
TextButton(
onPressed: () async {
var typedName = await Navigator.push(
context, MaterialPageRoute(
builder: (context){
return CityScreen();
},
),
);
try {
if (typedName != null) {
var cityweather = await WeatherModel().getCityWeather(typedName);
updateUi(cityweather);
}
} catch (e) {
print('An Error has occured, please try again');
}
},
child: Icon(Icons.location_city,
size: 50,
),
),
],
),
SizedBox(height: 60,),
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(cityName!, style: kMessageTextStyle,),
SizedBox(height: 8,),
Text('$temperature°',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 80),
),
SizedBox(height: 8,),
Text('$weatherState', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),),
],
),
),
],
),
),
),
);
}
}
I got: Instance of 'Future'!!! I think it's synchronization problem but I couldn't solve it.. In Advance, Thank you for your help.
Solution 1:[1]
Short Answer
Change your print statements to look like the following:
weathertype.fetchForecastDay().then((result){
print(result);
});
Long Answer
Its good practice in dart to type everything. Currently your fetchForecastDay returns just a Future that is not typed. This is bad practice as the compiler cannot tell what the return type is. Im not sure what the return type of getData is but my guess from googling is a Map<String, dynamic>?. Providing this will help the compiler figure out what is there.
This would change your fetchForecastDay to
Future<Map<String, dynamic>?> fetchForecastDay() async{
Location located = Location();
await located.getLocation();
NetworkHelper networkhelper = NetworkHelper('https://api.openweathermap.org/data/2.5/forecast?lat=${located.lattitude}&lon=${located.longitude}&appid=$apiKey&units=metric');
return await networkhelper.getData();
}
As for why its printing Future, your fetchForecastDay is async so you need to await it in some way. Given that you want to print it in functions that cannot be async, the easiest way is probably to do something like
weathertype.fetchForecastDay().then((result){
print(result);
});
Execution will continue before this print completes but it will allow you to see the result of that function call in the terminal.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Zach |
