I'm trying to have an auth guard on every page of my Angular app. I can't get this to work for lazily loaded modules using the import() syntax.
My lazy feature module:
const routes: Routes = [
{path: '', component: ExerciseGroupsMainPageComponent},
{path: 'register-interests', component: RegisterInterestsComponent},
{path: 'available-groups', component: AvailableGroupsPageComponent},
{path: 'upcoming-sessions', component: UpcomingSessionsComponent}
]
@NgModule({
declarations: [
LocationsListComponent,
LocationGroupsComponent,
InterestCardComponent,
TimeAfterDirective,
RegisterInterestsComponent,
AvailabilityCardComponent,
ExerciseGroupsMainPageComponent,
AvailableGroupsComponent,
AvailableGroupsPageComponent,
UpcomingSessionsComponent
],
imports: [
CommonAngularModule,
LayoutModule,
AppMaterialModule,
FormsModule,
FirebaseModule,
CommonModule,
RouterModule.forChild(routes)
],
providers: [
InterestsService,
ActivitiesService,
AvailabilitiesService
]
})
export class ExerciseGroupsModule { }
my main app routing module:
export const routes: Routes = [
{path: '', redirectTo: 'groups', pathMatch: 'full'},
{path: '', canActivateChild: [LoggedInGuard], children: [
{component: RoutineListComponent, path: 'routines'},
{component: SessionRunComponent, path: 'run-session', canActivate: [SessionRunGuard]},
{component: RoutineConfigComponent, path: 'routine-config/:id'},
]},
{
path: 'groups',
canLoad: [LoggedInGuard],
canActivateChild: [LoggedInGuard],
canActivate: [LoggedInGuard],
loadChildren: () => import('./exercise-groups/exercise-groups.module')
.then(m => m.ExerciseGroupsModule)
},
{component: LoginComponent, path: 'login'}
];
@NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
My login guard:
@Injectable({
providedIn: 'root'
})
export class LoggedInGuard implements CanActivateChild, CanLoad, CanActivate {
constructor(private auth: AuthService, private router: Router, private snackBar: MatSnackBar) {}
canActivateChild(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.auth.user$.pipe(
map(u => {
if (!u){
this.router.navigate(['login']);
this.snackBar.open('Please login or register to continue', 'OK');
}
return !!u;
})
);
}
canLoad(route: Route, segments: UrlSegment[]): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
console.log('canLoad called');
return this.canActivateChild(null, null);
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
return this.canActivateChild(null, null);
}
}
I thought this would cause navigating to /upcoming-sessions in my feature module to navigate back to the login page when there was no user. However, the page still displays and no navigation occurs.If I put a console statement in all methods of the guard, they are not hit. How can I get the lazy-loaded children to be guarded?