William Humphries
William Humphries

Reputation: 568

Await in Async not waiting to Completion

I've read through Async/Await/then in Dart/Flutter to try to understand why the await in my aysnc function doesn't wait until completion before moving on. In my UI, there is a button that calls an async method to return a location, the location always returns null and doesn't wait for the function to complete.

   onChanged: (newValue) async {
      setState(() {
        _selectedLocation = newValue;
      });
      if (_selectedLocation == "Set Location") {
        location = await runPlacePicker(context);    // <- Calling the method here
        _selectedLocationText = location.lat.toString();
      }

  Future<Location> runPlacePicker(context) async {   // <- Should return a Location value after popup
    Timer _throttle;
    PlacePicker result;
    Location location;
    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => PlacePicker(
                  apiKey: "",
                  onPlacePicked: (result) {
                    print(result.formattedAddress);
                    Navigator.of(context).pop();
                    location = result.geometry.location;
                    return location;
                  },
                  initialPosition: LatLng(0,0),
                  resizeToAvoidBottomInset: true,
                  useCurrentLocation: true,
                )
        )
    );
    if (location == null) {
      return null;
    } else {
      return location;
    }
  }

The function pushes a call to a new UI page that selects a location and should return a result, how can I make the function wait for the result? Am I not using async right?

Upvotes: 0

Views: 437

Answers (1)

Crizant
Crizant

Reputation: 1661

You can use Navigator.of(context).pop(location) to return the result from PlacePicker.

The code can be simplified to:

Future<Location> runPlacePicker(context) async {
  final Location location = await Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => PlacePicker(
        apiKey: "",
        onPlacePicked: (result) {
          Navigator.of(context).pop(result.geometry.location);
        },
        initialPosition: LatLng(0,0),
        resizeToAvoidBottomInset: true,
        useCurrentLocation: true,
      )
    )
  );
  return location;
}

Upvotes: 1

Related Questions