Reputation: 12790
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
},
]
},
];
Upvotes: 3
Views: 9239
Reputation: 1512
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',
}
Upvotes: 1
Reputation: 559
In my case (topic is similar) when I was getting loop it was AuthGuard on Login route.
{ path: 'login', component: LoginFormComponent, canActivate: [AuthGuard], }
To fix this I just removed guard from Login route.
Upvotes: 0
Reputation: 1059
For my problem, the order of import impacts on this error.
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
CommonModule,
AccountModule, // Load other eager modules first
AppRoutingModule // Move this AppRouting to the end like this
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
Upvotes: 0
Reputation: 8947
I don't have an exact soution for you, just a few this suggestions for debugging. Try expressing this as:
const routes: Routes = [
{
path: '',
component: LoginLayoutComponent,
children: [
{
path: 'login',
component: LoginComponent
},
{
path: '',
component: LoginComponent,
pathMatch: 'full'
},
]
}
to see if it is the route redirect.
Try replacing this with,
this.router.navigateByUrl('/login');
or
this.router.navigate(['', 'login']);
Upvotes: 0
Reputation: 39462
redirectTo
value should always have a leading /
as it represents the actual route the user should be navigated to.
Change redirectTo: 'login',
to redirectTo: '/login',
in your Route Config
Also, this:
this.router.navigate(['login']);
should be
this.router.navigate(['/login']);
Upvotes: 0