How to display alert dialog box on back button of browser or onReload the page using Go Router in flutter web?
Asked Answered
F

2

8

I am working on the Flutter web and using go_router for navigation.

Expectation: From the initial route, When the user tries to navigate back using the browser back button or reload the page, an alert box should be displayed and ask, "Are You sure you want to exit?" Kind of message and on User interaction page allows to exit or stay on the same page.

Tried Approaches:

1. WillPopScope:

I have added the WillPopScope widget on HomeRoute Widget to detect popCallBack. but Somehow It is not being triggered on the back button pressed because might I have used go_router for Navigation.

By executing the Below statement I am not able to print the log on the console onBack event.

return WillPopScope(
      onWillPop: () async {
        print("on Will Pop is Called");
        return false;
      },
      child: PaintScaffold(...)
);

BackButtonDispatcher of MaterialApp.router is only applicable on android, not on the web. So it is not going to work. Reference of it.

2. onBeforeUnload listener

I have tried to add the script on the index.html file to detect the onBeforeUnload event. But Its behavior is unexpected. It works fine in the chrome browser but in safari, it does not show an alert box on backButton pressed. But work on reloading the page.

on the iOS safari browser, onBeforeUnload is not being triggered in any of the cases when the page unloads.

  <script>
    window.addEventListener('load', function(ev) {
      // Download main.dart.js
      _flutter.loader.loadEntrypoint({
        serviceWorker: {
          serviceWorkerVersion: serviceWorkerVersion,
        }
      }).then(function(engineInitializer) {
        return engineInitializer.initializeEngine();
      }).then(function(appRunner) {
        return appRunner.runApp();
      });
    });

     window.onunload = window.onbeforeunload = function(){
       return 'Are you sure you want to leave?';
     };
  </script>

So Is there any other approach to resolve this issue when the user tries to exit the page then it will show an alert box to ask for confirmation?

Thank you.

Fulfil answered 7/9, 2022 at 7:15 Comment(1)
It may not be the issue in Flutter Web. Check this – Lombok
C
0

In the router config, you can add an onExit function to each route. If this function returns true, the route will exit normally. If this function returns false, the route will not be removed:

final router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const Home(),
    ),
    GoRoute(
      path: '/screen_one',
      builder: (context, state) => const ScreenOne(),
      onExit: (context, state) async {
        bool confirm = await showDialog<bool>(
              context: context,
              builder: (context) {
                return Center(
                  child: ConstrainedBox(
                    constraints: const BoxConstraints(
                      maxWidth: 400,
                    ),
                    child: Dialog(
                      backgroundColor: Colors.blue.shade200,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10),
                      ),
                      child: Padding(
                        padding: const EdgeInsets.all(24.0),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            const Center(
                              child: Text(
                                'Go Back?',
                                style: TextStyle(
                                  fontSize: 28,
                                ),
                              ),
                            ),
                            const SizedBox(height: 16),
                            ElevatedButton(
                              onPressed: () {
                                Navigator.of(context).pop(true);
                              },
                              child: const Text('Yes, Start Over'),
                            ),
                            const SizedBox(height: 16),
                            ElevatedButton(
                              onPressed: () {
                                Navigator.of(context).pop(false);
                              },
                              child: const Text('No, Cancel'),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                );
              },
            ) ??
            false;

        return confirm;
      },
    ),
    GoRoute(
      path: '/screen_two',
      builder: (context, state) => const ScreenTwo(),
    ),
  ],
);
Cox answered 20/8, 2024 at 14:53 Comment(0)
B
-1

Extend Observer from NavigatorObserver


Code

 GoRouter(
  initialLocation: '/',
  navigatorKey: _rootNavigatorKey,
  observers: [
    GoRouterObserver(), πŸ‘ˆ Specify your observer here
  ],
  routes: [
    GoRoute(
      ...
    )
    GoRoute(
      ...
    ),
  ],
);

class GoRouterObserver extends NavigatorObserver {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    showDialog() πŸ‘ˆ Here show your dialog box
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
   showDialog() πŸ‘ˆ Here show your dialog box
  }

  @override
  void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
   showDialog() πŸ‘ˆ Here show your dialog box
  }

  @override
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
    showDialog() πŸ‘ˆ Here show your dialog box
  }
}
Bussy answered 4/1, 2023 at 3:17 Comment(0)

© 2022 - 2025 β€” McMap. All rights reserved.