flutterdialogflutter-go-routergorouter

How can I navigate to a new screen from a dialog using GoRouter?


I am using GoRouter for route navigation which is implemented correctly and works fine for all route navigation. To navigate back to the previous screen, I require user confirmation. For this, I am using a Dialog to prompt the confirmation. On click of "Yes" in the Dialog:

Navigator.pop(context);
context.go(previous route);

Navigator.pop should close the dialog, context.go should go back to the previous screen.. The following error is thrown:

The following assertion was thrown while handling a gesture:
No GoRouter found in context
'package:go_router/src/router.dart':
Failed assertion: line 516 pos 12: 'inherited != null'

When the exception was thrown, this was the stack: 
#2      GoRouter.of (package:go_router/src/router.dart:516:12)
#3      GoRouterHelper.go (package:go_router/src/misc/extensions.dart:25:16)
#4      _FoodWeeklyInputState.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:cgc/Screens/Input/Food%20And%20Drink/Input_Page_Food.dart:2704:43)

If Navigator.context(pop); is called without the dialog, the routing works as expected, and I can navigate back to the previous screen. However using navigation from within I Dialog, the Routing fails and throws the error. What is the correct implementation of Dialog navigation using GoRouter? I have too many dialogs across the app to declare Dialogs as Routes, I just need to be able to navigate back to the previous screen using a Dialog prompt. Any help greatly appreciated.


Solution

  • The issue occurs because when the dialog is shown, its context is different from the main context where GoRouter is registered. To fix this, pass the parent context when calling context.go() instead of using the dialog's context

    showDialog(
      context: context,
      builder: (BuildContext dialogContext) {
        return AlertDialog(
          title: Text('Confirmation'),
          content: Text('are you sure?'),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.pop(dialogContext); 
                context.go('/previousRoute'); 
              },
              child: Text('Yes'),
            ),
            TextButton(
              onPressed: () {
                Navigator.pop(dialogContext);
              },
              child: Text('No'),
            ),
          ],
        );
      },
    );
    
    

    this setup, dialogContext is used only for closing the dialog and it and this solution should solve your problem.