Multiple guards behavior still incorrect
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 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 - 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.