fluttergorouter

Flutter GoRouter not navigating to selected rouye


Router config returns the correct path upon selecting a category from the homescreen but not navigating to the desired CategoriesFeedScreen. Here are the 3 code files guigind this navigation and the issues. Please assist as I have tried to resolve this issue for 3 weeks now on my own and no luck. Thanks

Router config (goRouterProvider.dart)

final GlobalKey<NavigatorState> _rootNavigator = GlobalKey(debugLabel: 'root');
final GlobalKey<NavigatorState> _shellNavigator =
    GlobalKey(debugLabel: 'shell');

final goRouterProvider = Provider<GoRouter>(
  (ref) {
    bool isDuplicate = false;
    final notifier = ref.read(goRouterNotifierProvider);

    return GoRouter(
      navigatorKey: _rootNavigator,
      debugLogDiagnostics: true,
      initialLocation: '/',
      refreshListenable: notifier,
      redirect: (context, state) {
        final isLoggedIn = notifier.value;
        final isGoingToLogin = state.subloc == '/auth-screen';

        if (!isLoggedIn && !isGoingToLogin && !isDuplicate) {
          isDuplicate = true;
          return '/auth-screen';
        }
        if (isLoggedIn && isGoingToLogin && !isDuplicate) {
          isDuplicate = true;
          return '/';
        }

        if (isDuplicate) {
          isDuplicate = false;
        }

        return null;
      },
      routes: [
        GoRoute(
          path: '/landing',
          name: 'landing',
          builder: (context, state) => LandingScreen(key: state.pageKey),
        ),
        GoRoute(
          path: '/auth-screen',
          name: 'auth-screen',
          builder: (context, state) => AuthScreen(key: state.pageKey),
        ),
        ShellRoute(
          navigatorKey: _shellNavigator,
          builder: (context, state, child) =>
              BottomNavScreen(key: state.pageKey, child: child),
          routes: [
            GoRoute(
              path: '/',
              name: RouteConstants.homeRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: HomeScreen(
                    key: state.pageKey,
                  ),
                );
              },
              routes: [
              
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'categories/:name',
                  name: RouteConstants.categoriesRouteName,
                  pageBuilder: (context, state) {
                    return NoTransitionPage(
                      child: CategoriesFeedScreen(
                        name: state.params['name']!,
                        key: state.pageKey,
                      ),
                    );
                  },
                ),
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'brands/:id',
                  name: RouteConstants.brandsRoutename,
                  pageBuilder: (context, state) {
                    return NoTransitionPage(
                      child: BrandsNavRail(
                        id: int.parse(state.params['id']!),
                        key: state.pageKey,
                      ),
                    );
                  },
                ),
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'popular-products/:id',
                  name: RouteConstants.popularProductsRouteName,
                  pageBuilder: (context, state) {
                    return NoTransitionPage(
                      child: PopularProducts(
                        id: state.params['id']!,
                        key: state.pageKey,
                      ),
                    );
                  },
                )
              ],
            ),
            GoRoute(
              path: '/feeds',
              name: RouteConstants.feedsRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: FeedsScreen(
                    key: state.pageKey,
                  ),
                );
              },
              routes: [
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'details/:id',
                  name: RouteConstants.detailsRouteName,
                  pageBuilder: (context, state) {
                    // final id = state.params['id'].toString();
                    return NoTransitionPage(
                      child: ProductDetailsScreen(
                        id: state.params['id']!,
                        key: state.pageKey,
                      ),
                    );
                  },
                )
              ],
            ),
            GoRoute(
              path: '/cart',
              name: RouteConstants.cartRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: CartScreen(
                    key: state.pageKey,
                  ),
                );
              },
            ),
            GoRoute(
              path: '/account',
              name: RouteConstants.accountRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: AccountScreen(
                    key: state.pageKey,
                  ),
                );
              },
            )
          ],
        )
      ],
      errorBuilder: (context, state) => RouteErrorScreen(
        errorMsg: state.error.toString(),
        key: state.pageKey,
      ),
    );
  },
);

CategoriesFeedScreen:

class CategoriesFeedScreen extends HookConsumerWidget {
  final String name;
  const CategoriesFeedScreen({Key? key, required this.name}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final categoryName = ref.watch(categoryProvider);
    final productList = ref.watch(productProvider.notifier);

    final catProductList = productList.findByCatName(
      categoryName.toString(),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(name),
      ),
      body: GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 10,
          childAspectRatio: 2 / 3,
          mainAxisSpacing: 10,
        ),
        itemCount: catProductList.length,
        itemBuilder: (context, i) {
          return FeedsProduct(
            id: catProductList[i].id,
          );
        },
      ),
    );
  }
}

CategoryWidget:

class CategoryWidget extends HookConsumerWidget {
  CategoryWidget({Key? key, required this.i}) : super(key: key);
  final int i;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final categoryLabel = ref.watch(categoryProvider);

    return InkWell(
        onTap: () {
         
          return context.goNamed(
            RouteConstants.categoriesRouteName,
            params: {'name': categoryLabel[i].name.toLowerCase()},
          );
        },
        child: Container(

main.dart:

Widget build(BuildContext context, WidgetRef ref) {
    final router = ref.watch(goRouterProvider);
    final categoryLabels = ref.watch(categoryProvider.notifier);
    final productList = ref.watch(productProvider.notifier);
    // final themeStatus = ref.watch(
    //     themeProvider.notifier); // used to switch between dark and light modes
    useEffect(() {
      resetNewLaunch();
      productList.fetchProducts();
      categoryLabels.getCategoryLabels();

      return;
    }, const []);
    return ref.watch(authStateChangeProvider).when(
          data: (data) => ResponsiveSizer(
            builder: (context, orientation, screenType) {
              return MaterialApp.router(
                debugShowCheckedModeBanner: false,
                builder: BotToastInit(), // call BotToastInit
                // navigatorObservers: [BotToastNavigatorObserver()],
                // theme: AppTheme.myTheme(themeStatus.getTheme(), context),
                darkTheme: ThemeData.dark(),
                routeInformationParser: router.routeInformationParser,
                routeInformationProvider: router.routeInformationProvider,
                routerDelegate: router.routerDelegate,
              );
            },
          ),
          error: (error, stackTrace) => ErrorText(error: error.toString()),
          loading: () => const Loader(),
        );
  }
}

I am running the latest flutter version and goRouter package. Thanks a bunch for your help


Solution

  • Fixed the non-navigation issue. Changed the parentNavigatorKey in the sub-routes of the routerConfig file (goRouterProvider) from _shellNavigator to _rootNavigator which allows the new screens to display outside of the bottomwnavigator shell. The sub-routes simply refused to open inside of the bottomNav tabs even though the correct params and paths were being registered. .