Reputation: 451
The guards in Angular2 routing run in the order they are provided. But in the case of guards with observables, even if the first guard is true, angular ignores it, and only apply the result from the second guard's observable.
How can I solve this?
const mainRoutes: Routes = [
{
path: 'app',
component:MainComponent,
canActivate:[AuthGuard],
children:[
{ path: 'dashboard', component: DashboardComponent },
{ path: 'protectedRoute', component: ProtectedRouteComponent, canActivate:[Admin1Guard,Admin2Guard] }
]}
];
The first guard:
canActivate() :Observable<boolean>{
return this.authService.getUser().map(res=>{
if(res.user.role=="admin1")
return true;
}).take(1);
}
}
The second guard:
canActivate() :Observable<boolean>{
return this.authService.getUser().map(res=>{
if(res.user.role=="admin2")
return true;
}).take(1);
}
}
Upvotes: 0
Views: 1363
Reputation: 14077
I would refactor the role-checking logic into a single, generic CheckRoleGuard
service and attach the name of the role to check to the route via the data
property:
{
path: 'protectedRoute1',
component: SomeComponent,
canActivate: [CheckRoleGuard],
data: { allowedRoles: ['admin','editor'] }
},
{
path: 'protectedRoute2',
component: SomeComponent,
canActivate: [CheckRoleGuard],
data: { allowedRoles: ['admin'] }
}
And now for the the RoleGuard
service:
@Injectable()
class CheckRoleGuard {
constructor(private authService: AuthService) { }
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
// Retrieve the allowed roles from `route.data`.
const allowedRoles = route.data['allowedRoles'];
return this.authService.getUser()
.map(data => {
return allowedRoles.indexOf(data.user.role) !== -1;
});
}
}
Upvotes: 2