Home > Software engineering >  Problem with BuildContexts across sync gaps
Problem with BuildContexts across sync gaps

Time:12-31

I am trying to learn Flutter by following the Angela Yu course which seems to be a little outdated and I am facing this problem: "Do not use BuildContexts across async gaps", in the following code;

void getLocationData() async {
    Location location = Location();

    await location.getCurrentLocation();

    NetworkHelper networkHelper = NetworkHelper(
        'https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey&units=metric');

    var weatherData = await networkHelper.getData();

    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return LocationScreen(locationWeather: weatherData);
    }));
  }

I have tried to look at solutions online, but can't seem to find the answer to my query. Any feedback would be greatly appreciated.

P.s. I have tried to use:

if (mounted) {
      Navigator.push(context, MaterialPageRoute(builder: (context) {
        return LocationScreen(locationWeather: weatherData);
      }));
    }

But it doesn't seems to work either.

CodePudding user response:

you can try using the WidgetsBinding.instance.addPostFrameCallback method to schedule the navigation to occur after the build is complete:

void getLocationData() async {
    Location location = Location();

    await location.getCurrentLocation();

    NetworkHelper networkHelper = NetworkHelper(
        'https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey&units=metric');

    var weatherData = await networkHelper.getData();

    // Schedule the navigation to occur after the build is complete
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Navigator.push(context, MaterialPageRoute(builder: (context) {
        return LocationScreen(locationWeather: weatherData);
      }));
    });
  }

Or you can try moving the Navigator.push call inside the await networkHelper.getData() block, like this:

void getLocationData() async {
    Location location = Location();

    await location.getCurrentLocation();

    NetworkHelper networkHelper = NetworkHelper(
        'https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey&units=metric');

    var weatherData = await networkHelper.getData();
if(!mounted) return;

    // Navigate to the LocationScreen after the async call is complete
    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return LocationScreen(locationWeather: weatherData);
    }));
  }

CodePudding user response:

Use then for the await call.

   var weatherData = await networkHelper.getData().then((value){

   Navigator.push(context, MaterialPageRoute(builder: (context) {
      return LocationScreen(locationWeather: weatherData);
    }));

  })
  • Related