Roman Shirokov
Roman Shirokov

Reputation: 559

RouteObserver for GoRouter to catch go/goNamed transitions

I have been analyzing different navigator observers by 3rd party integrations (e.g., SentryNavigatorObserver, FirebaseAnalyticsObserver) to make identical for tools that don't have it by default. But I noticed that neither of these is really catching all route transitions. I see it when they display data in their corresponding consoles. Yes, it works with push/pop, but any transitions within the same level with go are not being tracked. Which is very annoying. Anybody knows the way to solve it?


For example,

The transition from /page to /page/detail is observed.

The transition from /pageA to /pageB is not.

Upvotes: 17

Views: 13600

Answers (2)

krishnaacharyaa
krishnaacharyaa

Reputation: 24910

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) {
    print('MyTest didPush: $route');
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    print('MyTest didPop: $route');
  }

  @override
  void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
    print('MyTest didRemove: $route');
  }

  @override
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
    print('MyTest didReplace: $newRoute');
  }
}

Upvotes: 29

Roman Shirokov
Roman Shirokov

Reputation: 559

Found the issue. Some of the root routes were built using pageBuilder and NoTransitionPage, so to avoid animation, since they are working as tabs.

But besides setting NoTransitionPage.key initializer argument, you also need to set NoTransitionPage.name for the routes to be recognized.

So, because I did not do that, the navigator saw all these routes as null, so it just didn't see them changing in between.


Example how it should be:

GoRoute(
    name: Routes.home,
    path: Routes.getPathNamed(Routes.home),
    pageBuilder: (context, state) => NoTransitionPage<void>(
      key: state.pageKey, // <--- note this
      name: state.name, // <--- note this
      child: ScaffoldWithBottomBarNav(body: Routes.getPageNamed(Routes.home)),
    ),
  ),

Upvotes: 15

Related Questions