Day 3 of 5
⏱ ~60 minutes
Angular in 5 Days — Day 3

Angular Router

Angular Router enables multi-page navigation without page reloads. This lesson covers route setup, dynamic parameters, lazy loading, and route guards for authentication.

Setting Up Routes

app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'users/:id', component: UserDetailComponent },
  // Lazy-loaded feature module
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module')
      .then(m => m.AdminModule),
    canActivate: [AuthGuard]
  },
  { path: '**', redirectTo: '' }  // 404 fallback
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}
app.component.html

Reading Route Parameters

user-detail.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

@Component({ ... })
export class UserDetailComponent implements OnInit {
  userId: string = '';

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) {}

  ngOnInit() {
    // Snapshot: read once on init
    this.userId = this.route.snapshot.paramMap.get('id') ?? '';

    // Observable: react to param changes in same component
    this.route.paramMap.subscribe(params => {
      this.userId = params.get('id') ?? '';
      this.loadUser();
    });
  }

  goBack() { this.router.navigate(['/users']); }
}

Route Guards

auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private auth: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (this.auth.isLoggedIn()) return true;
    this.router.navigate(['/login']);
    return false;
  }
}
ℹ️
Lazy loading with loadChildren splits your app into separate JavaScript bundles. Users only download the admin bundle when they navigate to /admin. This dramatically improves initial load time for large apps.
📝 Day 3 Exercise
Build a Multi-Page Blog App
  1. Create routes for: Home (post list), Post Detail (/posts/:id), About, and 404.
  2. Fetch posts from https://jsonplaceholder.typicode.com/posts in a service.
  3. On the detail page, use ActivatedRoute to get the :id and fetch that post.
  4. Add routerLink from each post card to its detail page.
  5. Generate an AuthGuard that reads a loggedIn flag from localStorage. Protect the About page to test it.

Day 3 Summary

  • RouterModule.forRoot(routes) in the root module; forChild(routes) in feature modules.
  • routerLink for navigation in templates; router.navigate() in TypeScript.
  • ActivatedRoute.snapshot.paramMap.get('id') for one-time reads; use the Observable version for param changes.
  • Lazy-load feature modules with loadChildren to keep initial bundle size small.
Finished this lesson?