Skip to main content
Practice Problems

Angular router: routing, guards, and lazy loading

Angular Router

The Angular Router maps URL paths to components, supports navigation guards, lazy loading, and nested routes.


Basic Setup

typescript
// app.routes.ts import { Routes } from '@angular/router'; export const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent }, { path: 'users/:id', component: UserDetailComponent }, { path: '**', component: NotFoundComponent }, // Wildcard ];
html
<!-- app.component.html --> <nav> <a routerLink="/" routerLinkActive="active">Home</a> <a routerLink="/about" routerLinkActive="active">About</a> </nav> <router-outlet></router-outlet> <!-- Route content renders here -->

Route Parameters

typescript
import { ActivatedRoute } from '@angular/router'; @Component({ /* ... */ }) export class UserDetailComponent implements OnInit { private route = inject(ActivatedRoute); ngOnInit() { // Snapshot (one-time read) const id = this.route.snapshot.paramMap.get('id'); // Observable (reacts to param changes) this.route.paramMap.subscribe(params => { const id = params.get('id'); this.loadUser(id!); }); } }

Lazy Loading

Load feature modules on demand to reduce initial bundle:

typescript
export const routes: Routes = [ { path: 'admin', loadComponent: () => import('./admin/admin.component') .then(m => m.AdminComponent), }, { path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.routes') .then(m => m.DASHBOARD_ROUTES), }, ];

Route Guards

canActivate — Protect routes

typescript
import { CanActivateFn } from '@angular/router'; export const authGuard: CanActivateFn = (route, state) => { const authService = inject(AuthService); const router = inject(Router); if (authService.isLoggedIn()) { return true; } return router.createUrlTree(['/login'], { queryParams: { returnUrl: state.url } }); }; // Usage in routes { path: 'dashboard', component: DashboardComponent, canActivate: [authGuard] }

canDeactivate — Prevent leaving

typescript
export const unsavedChangesGuard: CanDeactivateFn<FormComponent> = (component) => { if (component.hasUnsavedChanges()) { return confirm('You have unsaved changes. Leave anyway?'); } return true; };

Resolvers — Pre-fetch data

typescript
export const userResolver: ResolveFn<User> = (route) => { const userService = inject(UserService); const id = route.paramMap.get('id')!; return userService.getUserById(id); }; // Route config { path: 'users/:id', component: UserDetailComponent, resolve: { user: userResolver } } // In component export class UserDetailComponent { private route = inject(ActivatedRoute); user = this.route.snapshot.data['user'] as User; }

Nested Routes

typescript
{ path: 'settings', component: SettingsLayoutComponent, children: [ { path: '', redirectTo: 'profile', pathMatch: 'full' }, { path: 'profile', component: ProfileSettingsComponent }, { path: 'security', component: SecuritySettingsComponent }, { path: 'notifications', component: NotificationSettingsComponent }, ] }

Programmatic Navigation

typescript
export class AppComponent { private router = inject(Router); goToUser(id: string) { this.router.navigate(['/users', id]); } goWithQuery() { this.router.navigate(['/search'], { queryParams: { q: 'angular', page: 1 } }); } }

Important:

Angular Router provides declarative routing with guards for access control and lazy loading for performance. Use functional guards (CanActivateFn) over class-based guards. Always lazy load feature routes using loadComponent/loadChildren. Use resolvers to pre-fetch data before navigation.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems