Advanced Router Configurations in Angular
Angular's router provides powerful and flexible features for navigating between views or pages. This guide covers various advanced router configurations to enhance your Angular applications.
Lazy Loading Modules
Lazy loading helps to load feature modules only when they are needed. This improves the performance of your application:
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Preloading Modules
Preloading modules can further improve the performance by loading feature modules in the background after the application is bootstrapped:
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Route Guards
Route guards determine whether a route can be activated, deactivated, or loaded. Implement CanActivate
guard:
// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
Use the guard in your routes:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule), canActivate: [AuthGuard] }
];
Resolve Guard
The Resolve
guard performs data fetching before the route is activated:
// data-resolver.service.ts
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataResolverService implements Resolve {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {
return of({ data: 'resolved data' });
}
}
Use the resolve guard in your routes:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule), resolve: { resolvedData: DataResolverService } }
];
Custom Preloading Strategy
Create a custom preloading strategy to selectively preload modules:
// selective-preloading-strategy.service.ts
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SelectivePreloadingStrategy implements PreloadingStrategy {
preload(route: Route, load: () => Observable): Observable {
return route.data && route.data['preload'] ? load() : of(null);
}
}
Use the custom preloading strategy in your routes:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule), data: { preload: true } }
];
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: SelectivePreloadingStrategy })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Child Routes
Define child routes to create nested routes:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: '', redirectTo: 'overview', pathMatch: 'full' },
{ path: 'overview', component: OverviewComponent },
{ path: 'details', component: DetailsComponent }
]
}
];
Lazy Loading with Named Outlets
Lazy load modules with named outlets to create complex routing scenarios:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule) },
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
outlet: 'sidebar'
}
];
Key Points
- Lazy loading modules improves application performance by loading feature modules only when needed.
- Preloading modules further enhances performance by loading feature modules in the background.
- Route guards, such as
CanActivate
andResolve
, provide fine-grained control over route activation and data fetching. - Create custom preloading strategies to selectively preload modules based on custom logic.
- Define child routes to create nested routing structures.
- Lazy load modules with named outlets to create complex and dynamic routing scenarios.
Conclusion
Advanced router configurations in Angular allow you to create sophisticated and efficient navigation structures in your applications. By using features such as lazy loading, preloading, route guards, custom preloading strategies, child routes, and named outlets, you can enhance the performance and usability of your Angular applications. Happy coding!