When you show a dialog in your Flutter app, sometimes you need to know what the user did inside that dialog. Maybe they clicked 'Yes', 'No', or chose an option.
Why the Common Mistake Happens
Some developers try to run code right after they call Navigator.of(context).pop();
inside the button press handler of the dialog. They expect this code to run just before or as the dialog closes.
The Problem
When you call Navigator.pop()
, the dialog is removed from the screen's navigation stack. Any code you try to execute immediately after pop()
might not finish or even start reliably because the context or widget tree state is changing rapidly as the dialog disappears. This can lead to unexpected bugs or behavior.
The Correct Way to Get a Result
Flutter's Navigator.pop()
method has a useful feature: you can pass a value to it!
Passing the Result
Instead of just Navigator.of(context).pop();
, you can use Navigator.of(context).pop(yourResult);
. Here, yourResult
is the value you want to send back to the code that showed the dialog.
Receiving the Result
The function you used to show the dialog (like showDialog
or showModalBottomSheet
) actually returns a Future
. This Future
completes with the value that was passed to Navigator.pop()
when the dialog is dismissed.
Using await
To get the result, you use the await
keyword when calling the function that shows the dialog.
Future<void> _showMyDialog(BuildContext context) async {
final result = await showDialog<MyResultType>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(MyResultType.option1),
child: const Text('Option 1'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(MyResultType.option2),
child: const Text('Option 2'),
),
],
);
},
);
// Now you can safely use 'result' here
if (result != null) {
print('Dialog result: $result');
// Perform actions based on the result
}
}
By using Navigator.pop(result)
, you ensure the value is correctly passed back through the navigation system, and you can handle the result reliably after the dialog is fully dismissed and the Future
completes. This is the clean and recommended way to handle dialog results in Flutter.