skip to Main Content

I’m playing with the shellroute example from the repo for gorouter. It has this code for tab B:

  GoRoute(
    path: '/b',
    builder: (BuildContext context, GoRouterState state) {
      return const ScreenB();
    },
    routes: <RouteBase>[
      /// Same as "/a/details", but displayed on the root Navigator by
      /// specifying [parentNavigatorKey]. This will cover both screen B
      /// and the application shell.
      GoRoute(
        path: 'details',
        parentNavigatorKey: _rootNavigatorKey,
        builder: (BuildContext context, GoRouterState state) {
          return const DetailsScreen(label: 'B');
        },
      ),
    ],
  ),

I want to press the tab for "B", and not have it show content in B, but rather do precisely what /b/details shows: stacking this window with a completely replaced full screen.

I tried adding parentNavigatorKey: _rootNavigatorKey to the /b route, but it blows up without running, citing:

Error: Assertion failed:
route.dart:408
route.parentNavigatorKey == null ||
              route.parentNavigatorKey == navigatorKey
"sub-route's parent navigator key must either be null or has the same navigator key as parent's key"

Why can’t I have /b go to a full page display pushing itself on the stack, rather than require /b/details? There’s nothing really to show within the tabbed window for b. And the assertion is clear as mud… What is the explanation, so I can see if it’s a bug that it’s not properly doing what I ask?

2

Answers


  1. From what I have read on some GitHub issue this is expected behaviour (no bug).

    The easiest way to achieve this behaviour is to simply check the tab in the builder method in order to not use a shell for it:

    if (state.location.startsWith("/b")) {
          return child;
    } else {
        // build the shell as usual.
    }
    

    A basic working example could look like this: https://pastebin.com/4c3mGdYG

    Or if you prefer Discord (including a video): https://discord.com/channels/420324994703163402/421448406506930187/1130076296907591750

    Login or Signup to reply.
  2. The error you encountered is due to the way the parentNavigatorKey property is used in the GoRoute configuration. The purpose of the parentNavigatorKey is to specify a different Navigator for a nested route, and it must either be null or match the navigator key of the parent route.

    In your case, you want to navigate to a full-page display for route /b, which is not a nested route under /b/details. Therefore, using parentNavigatorKey for the /b route is not the correct approach.

    To achieve the behavior you want, you can modify the configuration of the /b route directly, without using parentNavigatorKey. Instead, you can handle the navigation to a full-page display within the builder of the /b route.

    Here’s an example of how you can modify the /b route to achieve the desired behavior:

    GoRoute(
      path: '/b',
      builder: (BuildContext context, GoRouterState state) {
        // Check if there's a navigation request to the details screen
        if (state.queryParams.containsKey('details')) {
          return const DetailsScreen(label: 'B');
        } else {
          // If not, show the regular content for /b (you can replace this with your own content)
          return const ScreenB();
        }
      },
    ),
    

    Now, when you press the tab for "B," it will show the regular content for /b. However, if you want to navigate to a full-page display, you can use the /b?details path to trigger the display of DetailsScreen in a full-page context.

    For example, you can use GoRouter.of(context).go('/b?details'); to navigate to the full-page display of DetailsScreen from within the /b route.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search