'Prevent or Catch Dialog on dismiss with (back button or clicking the barrier to quickly) or force to wait until ScaffoldMessenger.of finishes

I have a dialog that dismisses too fast and throws an

 Unhandled Exception: This widget has been unmounted, so the State no
 longer has a context (and should be considered defunct).

Before ScaffoldMessenger.of(context).showSnackbar(widget) can send the context to the SnackBar

screen1.dart:

 launchVendorCard(vendorId)  async {
    
   vendorCardResult = await showDialog(context: context,
                builder: (builder) => VendorCard(vendorId));  }

vendorcard.dart:

Widget build(BuildContext context)  {
 return Dialog( 
           ...
          ElevatedButton(

          child: Text(buttonText,),

          onPressed:  () async {
                var snack =  await SnackBar(
                content: Text("$vendorTitle"),

                duration: Duration(seconds: 3),);

              await ScaffoldMessenger.of(context).showSnackBar(snack);
              Navigator.of(context, rootNavigator: true).pop(true);
              // Navigator.pop(context, true); )
)

How do I prevent this? await doesnt work. Gets triggered by quickly pressing close button, or tapping outside the barrier too quickly



Solution 1:[1]

You can wait after the SnackBar is dimissed with the SnackbarClosedReason by using the closed. It returns a Future with the reason why the SnackBack got dismissed. After it has been dismissed, it will then execute the Navigator.pop()

var snack = SnackBar(content: Text("$vendorTitle"),duration: Duration(seconds: 3));

final snackBar = ScaffoldMessenger.of(context).showSnackBar(snack);

// Waits until SnackBar got dismissed
await snackbar.closed;

Navigator.of(context, rootNavigator: true).pop(true);

Solution 2:[2]

  • I used WillPopScope to catch the dismissal problem.
  • Disable my close button when there's an operation in the background that needs to finish.
  • Moved the Snackbar() to the main page and just pass the info I need from the Dialog() by creating a map that is passed to Navigator.of(context, rootNavigator: true).pop(map_object);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 quoci
Solution 2 NinFudj