modular icon indicating copy to clipboard operation
modular copied to clipboard

Multiple guards behavior still incorrect

Open 3ph opened this issue 2 years ago • 2 comments

Currently when using multiple guards when first guard fails rather than redirecting to the first failed guard route it just continues through all the routes and returns last failed guard redirect.

Example:

...
  @override
  void routes(RouteManager r) {
    r.child(
      '/',
      child: (context) => Page(),
      guards: [
        AGuard(),
        BGuard(),
        CGuard(),
      ],
    );
  }
...

class AGuard extends RouteGuard {
  AGuard() : super(redirectTo: '/a');

  @override
  Future<bool> canActivate(String path, ModularRoute router) async {
    return true;
  }
}

class BGuard extends RouteGuard {
  BGuard() : super(redirectTo: '/b');

  @override
  Future<bool> canActivate(String path, ModularRoute router) async {
    return false;
  }
}

class CGuard extends RouteGuard {
  CGuard() : super(redirectTo: '/c');

  @override
  Future<bool> canActivate(String path, ModularRoute router) async {
    return false;
  }
}

In the example above rather than redirecting to /b it will redirect to /c.

This issue was already addressed by https://github.com/Flutterando/modular/pull/745 but the PR was never merged and just deleted so the issue persists.

Note: there is a workaround to merge all the guards into one and use pos to figure out where to redirect but it seems wrong.

3ph avatar Oct 11 '23 22:10 3ph

@3ph take a look here

class GuardsScope extends RouteGuard {
  GuardsScope(this._guards);

  final List<RouteGuard> _guards;

  @override
  String? get redirectTo => _guards[currentGuardIndex].redirectTo;

  int currentGuardIndex = 0;

  @override
  FutureOr<bool> canActivate(String path, ParallelRoute<dynamic> route) async {
    for (final guard in _guards) {
      currentGuardIndex = _guards.indexOf(guard);
      final canActivate = await guard.canActivate(path, route);
      if (!canActivate) {
        return false;
      }
    }
    return true;
  }
}

you just pack this with your guards and pass this one as single guard . keep in mind that order matters.

Vatalion avatar Dec 12 '24 09:12 Vatalion

@Vatalion - thanks for that. A bit sad that this issue was reported more than a year ago, PR was even created but it's still not fixed.

3ph avatar Jan 28 '25 20:01 3ph