0

I am using [go_router: ^9.0.3][1] for navigation in my flutter application.But after navigate to home screen I dont want to go back to login screen when click the backbutton of my application. How can i achive in go_router?I need to clear the login and otp screen when navigate to home screen.But now when i press back button of phone it is navigate to otp screen. pushNamedAndRemoveUntil is missing in go_router.

static final GoRouter router = GoRouter(
    initialLocation: '/',
      routes: [
        GoRoute(
          name: AppRouteConstant.splashRoute,
          path: '/',
          pageBuilder: (context, state) {
            return MaterialPage(
                child: SplashWidget(
              isTokenValid: AuthService.authenticated,
              key: UniqueKey(),
            ));
          },
        ),
        GoRoute(
          name: AppRouteConstant.loginRoute,
          path: '/login',
          builder: (context, state) {
            return Login_Screen(
              key: UniqueKey(),
            );
          },
        ),
        GoRoute(
          name: AppRouteConstant.welcomeRoute,
          path: '/welcome',
          pageBuilder: (context, state) {
            return const MaterialPage(child: WelcomeScreen());
          },
        ),
        GoRoute(
          name: AppRouteConstant.mfaLoginWithOtpRoute,
          path: '/loginWithOtp',
          pageBuilder: (context, state) {
            return const MaterialPage(child: MFALoginScreen());
          },
        ),
        GoRoute(
          name: AppRouteConstant.navigationWidgetRoute,
          path: '/navigationWidget',
          pageBuilder: (context, state) {
            return const MaterialPage(child: NavigationWidget());
          },
        ),
        GoRoute(
          name: AppRouteConstant.profileRoute,
          path: '/profile',
          pageBuilder: (context, state) {
            return const MaterialPage(child: UserProfileScreen());
          },
        ),
        // GoRoute(
        //   name: AppRouteConstant.homeRoute,
        //   path: '/home',
        //   pageBuilder: (context, state) {
        //     return const MaterialPage(child: HomeScreen());
        //   },
        // ),
        GoRoute(
          name: AppRouteConstant.tvReplayRoute,
          path: '/tvReplay',
          pageBuilder: (context, state) {
            return MaterialPage(
                child: TVReplay(
                    filterdata: state.queryParameters['filterData'],
                    flag: bool.parse(state.queryParameters['flag']!)));
          },
        ),
        GoRoute(
          name: AppRouteConstant.movieDetailsRoute,
          path: '/movieDetails',
          pageBuilder: (context, state) {
            return const MaterialPage(child: MovieDetails());
          },
        ),
        GoRoute(
          name: AppRouteConstant.commonSearchRoute,
          path: '/search',
          pageBuilder: (context, state) {
            List<Movie> genres = state.extra as List<Movie>? ?? [];
            return MaterialPage(
                child: Search(
              movies: genres,
            ));
          },
        ),
        GoRoute(
          name: AppRouteConstant.selectionListRoute,
          path: '/selectionList',
          pageBuilder: (context, state) {
            return MaterialPage(
                child: selectionList(
                    filterData: state.queryParameters["filterData"]));
          },
        ),
        GoRoute(
          name: AppRouteConstant.selectedSeriesScreenRoute,
          path: '/selectedSeries',
          pageBuilder: (context, state) {
            return MaterialPage(child: SelectedSeriesScreen());
          },
        ),
        GoRoute(
          name: AppRouteConstant.locationRoute,
          path: '/location',
          pageBuilder: (context, state) {
            return const MaterialPage(child: LocationPage());
          },
        ),
        GoRoute(
          name: AppRouteConstant.bluetoothRoute,
          path: '/bluetooth',
          pageBuilder: (context, state) {
            return const MaterialPage(child: Bluetooth_Screen());
          },
        ),
        GoRoute(
          name: AppRouteConstant.sliderRoute,
          path: '/slider',
          pageBuilder: (context, state) {
            return const MaterialPage(child: CircularSlider());
          },
        ),
        GoRoute(
          name: AppRouteConstant.customUIRoute,
          path: '/customUI',
          pageBuilder: (context, state) {
            return const MaterialPage(child: CustomUi());
          },
        ),

      ],
      errorPageBuilder: (context, state) {
        return MaterialPage(
            child: Scaffold(
          body: Text(state.error.toString()),
        ));
      },
      redirect: (context, state) {
        print("state is ${state.location}");
        if (AuthService.authenticated && state.location == '/login') {
          return '/navigationWidget';
        } else {
          return null;
        }
      });

I logged in to navigationWidget.But when i click the default backbutton of phone or web it is navigating to login screen.

Developer
  • 148
  • 8

1 Answers1

0

With declarative routing, e.g. with go_router, it's not possible to control with functions like pushNamedAndRemoveUntil, instead it needs to be declarative.

for example you have pages 'Login' and 'Home',

GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomeScreen(),
      redirect: (BuildContext context, GoRouterState state) {
        if (AuthState.of(context).isLoggedIn) {
          return '/login';
        } else {
          return null;
        }   
      },
    ),
    GoRoute(
      path: '/login',
      builder: (context, state) => const LoginScreen(),
    ),
  ],
);
'/' -> home route, but with redirect (to login) if not authenticated.
'/login' -> login route

On redicrect read this. But after all I'd recommend reading all documentation there, it's not a lot, but definitely contains solution of the issue.

Here's example on which BackButton pressing closing the app, without showing login page.

ValueNotifier<bool> loggedIn = ValueNotifier(false);

final _router = GoRouter(
  debugLogDiagnostics: false,
  navigatorKey: _rootKey,
  initialLocation: '/',
  routes: <RouteBase>[
    GoRoute(
      path: '/login',
      builder: (context, state) {
        return Scaffold(
          appBar: AppBar(
            actions: [
              IconButton(
                onPressed: () {
                  loggedIn.value = !loggedIn.value;
                  context.go('/');
                },
                icon: const Icon(Icons.add),
              ),
            ],
          ),
          body: Center(
            child: ValueListenableBuilder(
              valueListenable: loggedIn,
              builder: (context, value, child) => Text('loggedIn: $value'),
            ),
          ),
        );
      },
    ),
    GoRoute(
      path: '/',
      redirect: (context, state) {
        if (!loggedIn.value) {
          return '/login';
        }
      },
      builder: (context, state) {
        return const Center(child: Text('home'))
      },
    ),
  ],
);
ermekk
  • 66
  • 5