I've got this routes
{
path: 'user',
canLoad: [AuthGuard],
loadChildren: () =>
import('./user/user.module').then((m) => m.PublicUserModule)
}
{
path: '',
component: PublicUserPageComponent,
canActivate: [UserPhonesCheckGuard],
children: [
/*{
path: '',
pathMatch: 'full',
redirectTo: 'check'
},*/
{
path: 'account',
loadChildren: () =>
import('./account/user-account.module').then(
(m) => m.PublicUserAccountModule
)
},
{
path: 'check',
loadChildren: () =>
import('./check/user-check.module').then(
(m) => m.PublicUserCheckModule
)
}
]
}
Using UserPhonesCheckGuard depending on some conditions I want to redirect or to the check or to account children route but with
canActivate()
return this.router.parseUrl('/user/check');
}
the browser go nuts :(
What path should I use?
In this way;
canActivate()
return this.router.parseUrl('/user/check');
}
an infinite loop occurs.
Because when you return a UrlTree
(which is returned by this.router.parseUrl
) from canActivate
current navigation is cancelled and a new navigation started.
Since new navigation is going to a sub url (child) of current navigation, canActivate
guard runs again for the new navigation which in turn causes an infinite loop.
That's why you need a way to detect child navigation in canActivate
and break the infinite loop. One way of detecting child navigation can be to control the url. Such as;
canActivate(next: ActivatedRouteSnapshot,state: RouterStateSnapshot) {
console.log(state.url)
if(state.url === "/user/check" || state.url === "/user/account")
return true;
if(someCondition) /* here you determine which child to navigate */
return this.router.parseUrl('/user/check');
else
return this.router.parseUrl('/user/account');
}
I created a simple demo here. In the demo, you can see in the console that canActivate
runs twice for every navigation. One for the parent navigation and one for the child navigation. Without if condition, parent navigation would run indefinitely.
I hope it helps.