5

On application start i have a few configuration pages (that can be skipped by user) that user setup once, and finally ends up in dashboard page.

Possible navigation flows (depend on what user already setup, and what skipped in the past):

'/' -> '/dashboard'
'/' -> '/language' -> '/dashboard'
'/' -> '/welcome'/ -> '/dashboard'
'/' -> '/welcome'/ -> '/language' -> '/dashboard'

If i go from /welcome to /language I use context.push('/language') to be able to navigate back - but i am aware that it can be redirected to /dashboard. so if i go from anywhere to /dashboard, i always want to end up with clear navigation history, so that if user click backButton on dashboard, the application should shut down and there is no back arrow in dashboard AppBar.

final router = GoRouter(
  routes: <GoRoute>[
    GoRoute(
      path: '/',
      redirect: (_, __) => '/welcome',
    ),
    GoRoute(
      path: '/welcome',
      builder: (_, __) => const WelcomePage(),
      redirect: (_, __) async {
        final skip = await ...
        if (skip) {
          return '/language';
        }

        return null;
      },
    ),
    GoRoute(
      path: '/language',
      builder: (_, __) => const LanguagePage(),
      redirect: (_, __) async {
        final skip = await ...
        if (skip) {
            /*
            * TODO MAKE SOME MAGIC HERE TO CLEAR HISTORY
            */
            return '/dashboard';
        }

        return null;
      },
    ),
    GoRoute(
      path: '/dashboard',
      builder: (_, __) => const DashboardPage(),
    ),
  ],
);
Michał Dziwota
  • 838
  • 7
  • 16

1 Answers1

0

I'll repost this answer here as well.

This is what seems to have worked for me. I admit it's kind of a hack.

  1. Have a global GoRouter instance
GoRouter? globalGoRouter;

GoRouter getGoRouter() {
  return globalGoRouter ??= getRoutes();
}

GoRouter getRoutes() {
return GoRouter(
    initialLocation: '/',
    routes: <RouteBase>[
      GoRoute(
        path: '/',
        builder: (BuildContext context, GoRouterState state) {
          return const HomePage();
        },
        routes: <RouteBase>[
          GoRoute(
            name: 'auth',
            path: 'auth',
            builder: (BuildContext context, GoRouterState state) {
              return const AuthScreen();
            },
          ),
          GoRoute(
            name: 'login',
            path: 'login',
            builder: (BuildContext context, GoRouterState state) {
              return const LoginScreen();
            },
          ),
          GoRoute(
            name: 'landing',
            path: 'landing',
            builder: (BuildContext context, GoRouterState state) {
              return const LandingScreen();
            },
          ),
        ),
      ],
   );
}
  1. Create this function
void clearAndNavigate(String path) {
  while (getGoRouter().canPop() == true) {
    getGoRouter().pop();
  }
  getGoRouter().pushReplacement(path);
}
  1. Then you call the function
clearAndNavigate('login');

Open to suggestions for a less 'hacky' way

alfiepoleon
  • 1,781
  • 1
  • 16
  • 18