I'm new to flutter and I'm trying to get a location weather by https://openweathermap.org/ free api. everything is working fine but when I try to use my global variables in my build method to show them in the main page of the application all the variables are reinitialized and get null. It seems using global variables is not such a good idea to deal with the variables .. right? then shat should I do?
String Lon,Lat;
String cityName=""; //my global variable which I wish to show in the app
double? Temperature;
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: mainPage(),
),
);
}
class mainPage extends StatefulWidget {
@override
State<mainPage> createState() => _mainPageState();
}
class _mainPageState extends State<mainPage> {
@override
initState(){
super.initState();
getLocWeather();
}
@override
Widget build(BuildContext context) {
return MyScaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
cityName, //cityName goes null here
style: TextStyle(
color: Colors.blue,
fontSize: 50,
),
),
],
),
);
}
}
void getLocWeather() async{
Location location = Location();
await location.getLocation();
Lon = location.Longitude.toString();
Lat = location.Latitude.toString();
String url="https://api.openweathermap.org/data/2.5/weather?lat=${Lat}&lon=${Lon}&appid=${api_key}";
http.Response response =
await http.get(Uri.parse(url));
if (response.statusCode == 200) {
String data = response.body;
cityName = jsonDecode(data)['name'];
Temperature = jsonDecode(data)['main']['temp'];
// I get correct outputs here in my print logs
print(Lon);
print(Lat);
print(cityName);
print(Temperature);
}
}
CodePudding user response:
getLocWeather
is a future method, It will take some time to fetch data.
Try Future<void> getLocWeather() async{
and
@override
initState(){
super.initState();
getLocWeather().then((value)=>setState((){}));
}
CodePudding user response:
Use future builder widget instead to correctly render the widget once future completes, so you render the obtained value correctly.
see https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
CodePudding user response:
In your code, you are fetching the data in initState, and build is also called instantly after initState. As Futures take some time to execute, your build is getting called immediately after initState and using the values that are supposed to be initialized once the future call ends. To make sure that you only render the data once the data is fetched from the API, you can use the FutureBuilder from the flutter library.
Just wrap your body content with FutureBuilder and once the data is loaded show the data, else show some spinner or some loading screen or something to indicate that data is loading currently.
More on FutureBuilder here: https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html