I\'m working on an app that has a lot of roles that I need to use guards to block nav to parts of the app based on those roles. I realize I can create individual guard class
@AluanHaddad's solution is giving "no provider" error. Here is a fix for that (it feels dirty, but I lack the skills to make a better one).
Conceptually, I register, as a provider, each dynamically generated class created by roleGuard
.
So for every role checked:
canActivate: [roleGuard('foo')]
you should have:
providers: [roleGuard('foo')]
However, @AluanHaddad's solution as-is will generate new class for each call to roleGuard
, even if roles
parameter is the same. Using lodash.memoize
it looks like this:
export var roleGuard = _.memoize(function forRole(...roles: string[]): Type {
return class AuthGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable
| Promise
| boolean {
console.log(`checking access for ${roles.join(', ')}.`);
return true;
}
}
});
Note, each combination of roles generates a new class, so you need to register as a provider every combination of roles. I.e. if you have:
canActivate: [roleGuard('foo')]
and canActivate: [roleGuard('foo', 'bar')]
you will have to register both: providers[roleGuard('foo'), roleGuard('foo', 'bar')]
A better solution would be to register providers automatically in a global providers collection inside roleGuard
, but as I said, I lack the skills to implement that.