Reputation: 4189
In my angular 5 project I "protect" some views based on the logged user role, so in my routing module I have:
path: '',
component: AdminLayoutComponent,
canActivate: [AuthGuard],
canActivateChild: [RoleGuard],
children: [
{
path: '',
loadChildren: './dashboard/dashboard.module#DashboardModule',
data: { roles: ['role.all'] }
},
{
path: 'checkPoints',
loadChildren: './check-points/check-point-list/check-point-list.module#CheckpointListModule',
data: { roles: ['role.admin', 'role.tech', 'role.backoffice'] }
}...
AuthGuard check if the user is authenticated, and then RoleGuard check if the logged user has the role to see the page. But I see the canActivateChild method called multiple times when I try to navigate into child routes (2-3 times)
Is it correct behaviour?
Upvotes: 3
Views: 3081
Reputation: 3166
So something similar case happened to me. I am sharing here if it helps someone. More of a theoretical solution.
Above @Fateme Fazli's answer shows exact correct architecture in which it should be passed but still it would be called twice. Here is how to properly compute your checks in the 2nd run, skipping 1st.
TL;DR
It happens because despite you put a canActivateChild outside in parent.route.module.ts where we use loadChildren() => ... syntax; there is still one more individual route.module.t of child in which another routes object is defined with '' i.e empty path. So for Me, route.data was coming as undefined in 1st go, but actual data in 2nd go.
There are 2 solutions
Here I only talked about 1 level of nesting, imagine having 4 levels of nesting, and the guard is applied somewhere outside, it will be called for all those nested children.
Upvotes: 3
Reputation: 11982
{
path: "",
component: AdminLayoutComponent,
canActivate: [AuthGuard],
children: [
{
path: "",
canActivate: [RoleGuard],
children: [
{
path: '',
loadChildren: './dashboard/dashboard.module#DashboardModule',
data: { roles: ['role.all'] }
},...
i think this way would prevent 2-3 times.
Upvotes: 1