Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of back navigation in nested routes, ignored PopScope #1957

Open
HE-LU opened this issue May 21, 2024 · 3 comments
Open

Handling of back navigation in nested routes, ignored PopScope #1957

HE-LU opened this issue May 21, 2024 · 3 comments

Comments

@HE-LU
Copy link

HE-LU commented May 21, 2024

Hey, I am trying to understand how the Nested navigation is actually working, and why the PopScope is ignored. Also, I am looking for a way how to implement the following functionality:

  • I have a sample app with quite a long "onboarding". Each of the children's routes is a separate step.
  • IdentityVerificationRoute is a wrapper screen, that has AppBar, some fancy wrapping, and contains AutoRouter to display children.
  • Some of those screens actually have two states, and when the user hits the back button, I would like to STAY on that page. Sadly PopScope is not handled at all, and works correctly only on the first step, where the back button would invoke exiting the flow completely.

image

I am not sure if this is a bug or if I am just missing something. Is there another way how I should limit the back navigation? In the most ideal case, I would love to handle and limit the back directly on the specific step. Sadly, the PopScope is completely ignored there.

@HE-LU
Copy link
Author

HE-LU commented May 21, 2024

So, I come up with a theory.

Looks like PopScope implements PopEntry. registerPopEntry should always register to the top route, which happens inside didChangeDependencies() method. For me, this method is not called when pushing other children's routes. This mean that other children routes pushed atop, are not registered, and PopScopes canPopNotifier is not used.

@HE-LU
Copy link
Author

HE-LU commented May 22, 2024

So I think I finally solved the issue for my case. I will try to describe the solution as best I can.

Let's take for example one nested page from my example above, e.g. IdentityVerificationStepTaxId. This page has two "states" which means two content widgets. First _SelectIdTypeDataStateWidget and second _FillNationalIdDataStateWidget. This means, that once the user selects ID type, the second widget is presented to him.

My solution was to wrap the whole content inside _FillNationalIdDataStateWidget (the second one) with PopScope the following way:

return PopScope(
  canPop: false,
  onPopInvoked: (didPop) => stateNotifier.clearSelectTaxIdType(),
  child: Container(

This will handle the back button on that page, and always block the maybePop. It will also invoke the clearSelectTaxIdType, which will switch UI back to _SelectIdTypeDataStateWidget (the first one). The second widget gets disposed, including the PopScope handler, and on the second maybePop, the navigator will switch to the previous nested screen.

This solves half of my issue, with blocking of the navigation on a specific page. The second issue is to get notified every time the navigation changes, and I actually change the child navigation, which I am currently handling using NavigationObserver.

This means that on the root IdentityVerificationPage, I have a custom nav observer, and I am handling the pop there manually. Here is a code snippet:

class _NavigationObserver extends AutoRouterObserver {
  _NavigationObserver({
    required this.onDidPop,
  });

  final void Function() onDidPop;

  @override
  void didPop(Route route, Route? previousRoute) {
    onDidPop();
    super.didPop(route, previousRoute);
  }
}
AutoRouter(
  navigatorObservers: () => [
    _NavigationObserver(
      onDidPop: () => stateNotifier.onPopInvoked(),
    ),
  ],
)

@lushan1314
Copy link

i think u need this method context.router.popForced();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants