Welcome to our comprehensive guide on Angular Routing! This powerful system enables seamless navigation while maintaining the single-page application experience.
Why Angular Router?
- Creates bookmarkable URLs
- Enables browser history navigation
- Supports lazy loading
- Provides route guards for security
- Maintains application state
Basic Routing Setup
- First, importÂ
RouterModule:
typescript
// app.module.ts
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forRoot([
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
])
]
})
- Add the router outlet in your root template:
html
<!-- app.component.html --> <app-header></app-header> <router-outlet></router-outlet> <!-- Components render here --> <app-footer></app-footer>
Navigation Between Routes
Use routerLink for template navigation:
html
<nav> <a routerLink="/home" routerLinkActive="active">Home</a> <a routerLink="/about" routerLinkActive="active">About</a> </nav>
Or navigate programmatically:
typescript
// component.ts
constructor(private router: Router) {}
navigateToAbout() {
this.router.navigate(['/about']);
}
Route Parameters
1. Defining Routes with Parameters
typescript
{ path: 'products/:id', component: ProductDetailComponent }
2. Accessing Route Parameters
typescript
// Using ActivatedRoute
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.productId = this.route.snapshot.paramMap.get('id');
// For observable approach (react to changes):
this.route.paramMap.subscribe(params => {
this.productId = params.get('id');
});
}
3. Generating Links with Parameters
html
<a [routerLink]="['/products', product.id]">View Product</a>
typescript
// Programmatic navigation this.router.navigate(['/products', productId]);
Child Routes (Nested Views)
Create nested UI layouts:
typescript
{
path: 'admin',
component: AdminLayoutComponent,
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'users', component: UserListComponent }
]
}
html
<!-- AdminLayoutComponent template --> <h2>Admin Panel</h2> <nav> <a routerLink="dashboard">Dashboard</a> <a routerLink="users">Users</a> </nav> <router-outlet></router-outlet> <!-- Nested components appear here -->
Route Guards
Control route access:
1. CanActivate (Authentication Guard)
typescript
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['/login']);
return false;
}
}
2. CanDeactivate (Unsaved Changes Guard)
typescript
@Injectable()
export class UnsavedChangesGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
3. Registering Guards
typescript
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthGuard],
canDeactivate: [UnsavedChangesGuard]
}
Lazy Loading Modules
Dramatically improve initial load time:
typescript
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module')
.then(m => m.DashboardModule)
}
Advanced Routing Features
1. Route Resolvers (Pre-fetching Data)
typescript
@Injectable()
export class ProductResolver implements Resolve<Product> {
constructor(private productService: ProductService) {}
resolve(route: ActivatedRouteSnapshot) {
return this.productService.getProduct(route.paramMap.get('id'));
}
}
2. Custom Route Matchers
typescript
{
matcher: (url) => {
if (url[0].path.startsWith('product-')) {
return {
consumed: url,
posParams: {
id: new UrlSegment(url[0].path.substr(8), {})
}
};
}
return null;
},
component: ProductDetailComponent
}
3. Router Events
typescript
constructor(private router: Router) {
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe(event => {
console.log('Navigation ended:', event);
});
}
Best Practices
- Organize routes in a dedicated routing module
- Use lazy loading for feature modules
- Protect routes with appropriate guards
- Handle 404s with a wildcard route
- Preload strategies for better UX
Hands-On Exercise
Build a complete routing setup with:
- Authentication-protected admin section
- Product detail pages with resolvers
- Lazy-loaded feature modules
- 404 page for unmatched routes
What’s Next?
In Part 11, we’ll explore Forms in Angular – both template-driven and reactive approaches!
