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
},
]
},
];
EDIT: Found out the culprit! In app.module.ts you need to import AuthModule first. Doing this will allow you to use the path '**' in either 'auth-routing.module.ts' or 'app-routing.module.ts'
@NgModule({
imports: [
AuthModule,
AppRoutingModule,
BrowserModule,
HttpClientModule,
SharedModule
],
})
I was having an infinite loop issue as well. Not sure if this relates to yours but for me I had two routing files. 'app-routing.module.ts' and 'auth-routing.module.ts'. I moved the code below from ' app-routing.module.ts' into 'auth-routing.module.ts' and no more infinite loops! Hope this helps you in some way!
{
path: '**',
redirectTo: 'my-route',
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With