I'm doing an Angular application with the following routing:
const routes: Routes = [
{
path: '',
component: LoginLayoutComponent,
children: [
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
},
{
path: 'login',
component: LoginComponent
}
]
},
{
path: '',
component: HomeLayoutComponent,
canActivate: [AuthGuardService],
children: [
{
path: 'users',
component: UsersComponent,
},
{
path: 'detail/:id',
component: UserComponent,
},
{
path: 'dashboard',
component: DashboardComponent,
data: {
expectedRole: 'admin'
}
},
{
path: 'home',
loadChildren: './views/home/home.module#HomeModule',
data: {
preload: true,
delay: false
}
},
{
path: 'error',
component: ErrorComponent
},
]
},
];
If I'm not logged in and I request any secured url, like for example http://localhost:4200/users
or http://localhost:4200/dashboard
then there is a redirect to the http://localhost:4200/
and the application goes into an infinite loop. If I'm logged in then it works fine.
The browser console displays the following message Navigation triggered outside Angular zone
.
Here is my auth guard
service:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
const expectedRole = route.data.expectedRole ? route.data.expectedRole : null;
const tokenPayload = this.tokenService.getDecodedAccessToken();
return this.authService.isAuthenticated()
.pipe(
map(isAuth => {
if (!isAuth) {
this.router.navigate(['login']);
return false;
} else {
return true;
}
}),
catchError((error, caught) => {
return of(false);
})
);
}
canLoad(): Observable<boolean> {
if (this.authService.isAuthenticated()) {
return of(true);
} else {
return of(false);
}
}
I'm on Angular 7
EDIT: The issue is now resolved with the following auth guard:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.isAuthenticated()
.pipe(
map(isAuthenticated => {
if (!isAuthenticated) {
this.authService.setPostLoginRedirectUrl(state.url);
this.router.navigate(['login']);
return false;
} else {
return true;
}
}),
catchError((error, caught) => {
return of(false);
})
);
}
and the following routes:
const routes: Routes = [
{
path: '',
component: LoginLayoutComponent,
children: [
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
},
{
path: 'login',
component: LoginComponent
}
]
},
{
path: '',
component: HomeLayoutComponent,
canActivateChild: [AuthGuardService],
children: [
{
path: 'users',
component: UsersComponent,
},
{
path: 'detail/:id',
component: UserComponent,
},
{
path: 'dashboard',
component: DashboardComponent,
data: {
expectedRole: 'admin'
}
},
{
path: 'home',
loadChildren: './views/home/home.module#HomeModule',
data: {
preload: true,
delay: false
}
},
{
path: 'error',
component: ErrorComponent
},
]
},
];