Home > database >  How to pop a specific route through Navigator in an async function?
How to pop a specific route through Navigator in an async function?

Time:10-29

Is there a way to tie or bind the Navigator.pop() method to a specific route?

In my case, Navigator.pop() is called from an async function in a widget which takes some time to complete, such as:

ElevatedButton(
  onPressed: () async {
    await doSomethingAsync();
    if (mounted) {
      Navigator.pop(context);
    }
  },
  child: const Text("Do something async then pop")),
)

While that function is ongoing, it could happen however that:

  • The route could be popped ahead of time by the user pressing the Android back button (similarly to a previous question I made)
  • Another route could be pushed on top of the existing one by the user performing another action

In both cases, I'd like the navigator to "tie" to the specific route onto which the widget is displayed, and only pop it if it isn't yet.

What's the best way to do that? If that's not possible (or overly complicated) I am also open to solutions using the go_router package, for which the same question applies.

CodePudding user response:

you're better off using it like this

asyncFunction().then((value){
     Navigator.pop(context);
});

to make sure it won't navigate until the asyncFunction is done, and make sure the asyncFunction is a Future function

Future<someThing> asyncFunction()async
    {
      someLogic;
    }

CodePudding user response:

You can show a loading dialog while Future is working. It also helps to know to user that app is working on something.

ElevatedButton(
      onPressed: () async {
        showMyWaitingDialog(context);
        await doSomethingAsync();
        if (mounted) {
          Navigator.pop(context);
          Navigator.pop(context);
        }
      },
      child: const Text('Do something async then pop'),
    )

The dialog elswhere:

showMyWaitingDialog(BuildContext context) {
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (_) {
      return const AlertDialog(
        content: SizedBox(
          height: 60,
          child: Center(
            child: Text('Waiting for...'),
          ),
        ),
      );
    },
  );
}
  • Related