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

removeWhere removes the wrong route #1943

Open
hassan-saleh-ml opened this issue Apr 24, 2024 · 1 comment
Open

removeWhere removes the wrong route #1943

hassan-saleh-ml opened this issue Apr 24, 2024 · 1 comment

Comments

@hassan-saleh-ml
Copy link

hassan-saleh-ml commented Apr 24, 2024

We investigated an issue in our app after upgrading to the latest version of auto_route where if we have 2 routes of the same type in the stack, try to remove the second one using context.router.removeWhere, the topmost route is being removed.

Here's an example:

              context.replaceRoute(
                InfoRoute(
                  key: loaderKey,
                  canPop: false,
                  content: [
                    InfoScreenTitleSubtitle(
                      title: l10n.processing,
                      subtitle: l10n.loading,
                      addLoader: true,
                    ),
                  ],
                ),
              );

Then after loading is completed:

        context.pushRoute(
          InfoRoute(
            canPop: false,
            content: [
              successScreen(),
            ],
          ),
        );
         
        /// To keep the fade-in-out animation of the loader,
        /// we must just push the success screen instead of replacing the loader route.
        /// When closing the success screen the loader is visible for a little while,
        /// so the solution is to remove it like this.
        await Future.delayed(RouteConstants.routeClosureDelayDuration.ms);
        if (context.mounted) {
          context.router.removeWhere(
            (route) => route.isInfoRoute(withKey: loaderKey),
          );
        }
extension RouteDataExtensions on RouteData {
  /// Can be used to conveniently check if the Route is [InfoRoute].
  bool isInfoRoute({ValueKey? withKey}) {
    final args = this.args;
    if (args is! InfoRouteArgs) {
      return false;
    }

    if (withKey != null) {
      return args.key == withKey;
    }

    return true;
  }
}

This used to work just fine before the only difference was how we identify the route using the key, the key used to be in RouteData, now it lives in the argument class (InfoRouteArgs)

After investigating this we found the root cause which is in routing_controller.dart:

  void _removeRoute(RouteMatch route, {bool notify = true}) {
    var pageIndex = _pages.lastIndexWhere((p) => p.routeKey == route.key);
    if (pageIndex != -1) {
      _pages.removeAt(pageIndex);
    }

    _updateSharedPathData(includeAncestors: true);
    _removeTopRouterOf(route.key);
    if (notify) {
      notifyAll(forceUrlRebuild: true);
    }
  }

It used the route key to identify the route, however this key is the same for both screens, the key is set to the route's name which is InfoRoute.

@hassan-saleh-ml hassan-saleh-ml changed the title removeWhere r removeWhere removes the wrong route Apr 24, 2024
@nivisi
Copy link

nivisi commented May 2, 2024

@Milad-Akarie hi sir! Any chance you could guide us on how to resolve this issue? Is there any way to help AutoRoute to distinguish two different routes of the same type based on custom conditions?

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