Module Overview
Estimated Time: 3-4 hours | Difficulty: Intermediate | Prerequisites: Module 5
- Setting up routing configuration
- Router outlet and navigation
- Route parameters and query params
- Lazy loading for performance
- Route guards and resolvers
- Nested routes and layouts
Router Architecture
Basic Routing Setup
Configure Routes
Router Outlet
Route Parameters
Path Parameters
Modern: Input Binding for Route Parameters
Query Parameters
Programmatic Navigation
Lazy Loading
Load feature modules only when needed. Lazy loading is one of the highest-impact performance optimizations in Angular. Without it, your entire application — every feature, every admin page, every settings screen — gets downloaded upfront before the user sees anything. With lazy loading, the browser only downloads the code for the page the user is actually visiting. Additional pages load on demand as the user navigates.Route Guards
Protect routes with functional guards. Guards are the bouncers at the door of your routes — they decide who gets in and who gets redirected. Angular runs guards before the route activates, so the user never sees a flash of unauthorized content.Common pitfall: Never rely on route guards as your only security layer. Guards run on the client and can be bypassed by a determined user. Always verify permissions on the server side too. Guards are a UX convenience (redirecting unauthorized users to login), not a security mechanism.
canActivate - Protect Route Access
canDeactivate - Confirm Before Leaving
canMatch - Control Route Matching
Route Resolvers
Pre-fetch data before activating route:Nested Routes & Layouts
Router Events
Monitor navigation lifecycle:Router Configuration Options
Practice Exercise
Exercise: Build a Product Catalog with Routing
Create a multi-page app with:
- Product list page with category filters via query params
- Product detail page with tabs (info, reviews, specs)
- Auth guard protecting checkout route
- Lazy loaded admin section
- 404 page for unknown routes
Solution
Solution
Summary
1
Route Configuration
Define routes with path, component, and optional guards/resolvers
2
Navigation
Use RouterLink in templates or Router.navigate() programmatically
3
Lazy Loading
Use loadChildren/loadComponent for better initial load performance
4
Guards
Protect routes with canActivate, canDeactivate, canMatch
5
Resolvers
Pre-fetch data before route activation
Interview Deep-Dive
Q: Explain the difference between canActivate, canDeactivate, and canMatch guards. Give a real-world scenario where canMatch is the right choice over canActivate.
Q: Explain the difference between canActivate, canDeactivate, and canMatch guards. Give a real-world scenario where canMatch is the right choice over canActivate.
Strong Answer: canActivate runs after route matching and prevents navigation to a route — the user sees a redirect or error page. canDeactivate runs when leaving a route and can prevent navigation away — the classic “unsaved changes” confirmation. canMatch runs during route matching itself and affects which route definition is selected.The critical difference with canMatch: it controls route matching, not just access. If canMatch returns false, the router does not just block access — it acts as if that route definition does not exist and continues checking the next route definition with the same path.The perfect real-world scenario: role-based dashboards. You have an admin dashboard and a user dashboard, both at /dashboard. With canMatch, you define two route entries for the same path, each with a different canMatch guard checking the user’s role. When an admin navigates to /dashboard, canMatch on the admin route returns true, so they get AdminDashboardComponent. When a regular user navigates to /dashboard, canMatch on the admin route returns false, the router skips it, and matches the next route definition which loads UserDashboardComponent.You cannot do this with canActivate because canActivate runs after matching — it would match the first /dashboard route and then redirect, which changes the URL and creates a worse UX.Follow-up: Should you rely on route guards as a security mechanism?
Answer: Never as the sole mechanism. Route guards are a UX convenience layer. They prevent honest users from accidentally landing on pages they should not see, and they create smooth redirect-to-login flows. But guards run entirely on the client — a determined user can open DevTools, modify the guard’s return value, or directly call your API endpoints. Every authorization check must be enforced server-side. The guard prevents seeing a flash of the admin page; the API prevents actually accessing admin data.
Q: Walk me through how you would implement lazy loading for a large application with 20+ feature modules. What is your strategy for preloading?
Q: Walk me through how you would implement lazy loading for a large application with 20+ feature modules. What is your strategy for preloading?
Strong Answer: My approach: every feature that is not on the initial landing page gets lazy loaded. This means each feature has its own routes file exported as a constant, and the app.routes.ts uses loadChildren to point to it. The initial bundle only contains the shell (nav, footer), the landing page component, and the core services.For preloading strategy, I would not use PreloadAllModules blindly because it downloads everything immediately after initial load — fine for small apps, wasteful for large ones. Instead, I implement a custom PreloadingStrategy that prioritizes based on likelihood of navigation. For example, if analytics show 80% of users visit the product catalog after landing, I preload that first. Admin modules only preload if the user has an admin role.The implementation: create a class that implements PreloadingStrategy and its preload method. For each route, check a condition (role, analytics data, or a custom route data property like preload: true) and either call load() to preload or return EMPTY to skip.I also use @defer with prefetch on idle for component-level lazy loading within pages. So a product detail page lazy-loads its review section and recommendation carousel independently.The measurable impact: on a project I worked on, we reduced initial bundle from 2.1MB to 380KB by lazy loading features, and then reduced perceived load time further with strategic preloading so navigations to likely-next pages were instant.Follow-up: How do you verify that lazy loading is actually working and not accidentally pulling modules into the main bundle?
Answer: I use the Angular CLI’s ng build —stats-json flag to generate a webpack stats file, then visualize it with webpack-bundle-analyzer or source-map-explorer. These tools show exactly which modules are in which chunk. If a lazy module shows up in the main bundle, it means something in the main bundle imports from it directly — usually a shared barrel export (index.ts) that re-exports everything.
Next Steps
Next: Angular Forms
Master template-driven and reactive forms for user input