Skip to content
advanced Phase 8 · Routing and Navigation Guards

Listening to Router Events

React to navigation lifecycle events across the application.

40m
0 problems
Topic Progress 0%

Router Event Lifecycle

The Router emits events during each navigation lifecycle. You can subscribe to these events to react to navigation changes.

Router Event Types

import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';

@Component({
  selector: 'app-root',
  template: `...`,
})
export class AppComponent implements OnInit, OnDestroy {
  private router = inject(Router);
  private destroy$ = new Subject<void>();

  ngOnInit(): void {
    this.router.events.pipe(
      filter((event): event is NavigationEnd => event instanceof NavigationEnd),
      takeUntil(this.destroy$)
    ).subscribe(event => {
      console.log('Navigation ended:', event.url);
    });
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }
}

Event Sequence

NavigationStart
  → RoutesRecognized
  → GuardsCheckStart
  → ChildActivationStart
  → ActivationStart
  → GuardsCheckEnd
  → ResolveStart
  → ResolveEnd
  → ActivationEnd
  → ChildActivationEnd
  → NavigationEnd

Or on failure:

NavigationStart → NavigationCancel
NavigationStart → NavigationError

Filtering Events

import { filter } from 'rxjs/operators';

this.router.events.pipe(
  filter((event) => event instanceof NavigationStart)
).subscribe(event => {
  console.log('Navigation started:', event.url);
});

Practical Router Event Patterns

Router events enable common UX patterns like progress bars and analytics tracking.

Progress Bar

@Component({
  selector: 'app-progress-bar',
  template: `
    <div class="progress-bar" [style.width.%]="progress" *ngIf="isNavigating">
  `,
})
export class ProgressBarComponent implements OnInit, OnDestroy {
  private router = inject(Router);
  private destroy$ = new Subject<void>();
  isNavigating = false;
  progress = 0;

  ngOnInit(): void {
    this.router.events.pipe(
      takeUntil(this.destroy$)
    ).subscribe(event => {
      if (event instanceof NavigationStart) {
        this.isNavigating = true;
        this.progress = 0;
        this.animateProgress();
      }
      if (event instanceof NavigationEnd || event instanceof NavigationCancel) {
        this.progress = 100;
        setTimeout(() => this.isNavigating = false, 200);
      }
    });
  }

  private animateProgress(): void {
    const interval = setInterval(() => {
      if (this.progress < 90) {
        this.progress += 10;
      } else {
        clearInterval(interval);
      }
    }, 100);
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }
}

Analytics Tracking

@Injectable({ providedIn: 'root' })
export class AnalyticsService {
  private router = inject(Router);

  trackPageViews(): void {
    this.router.events.pipe(
      filter((event): event is NavigationEnd => event instanceof NavigationEnd)
    ).subscribe(event => {
      gtag('event', 'page_view', { page_path: event.url });
    });
  }
}

Scroll to Top on Navigation

this.router.events.pipe(
  filter((event): event is NavigationEnd => event instanceof NavigationEnd)
).subscribe(() => {
  window.scrollTo(0, 0);
});

Cancel In-Flight Navigation

this.router.events.pipe(
  filter((event): event is NavigationStart => event instanceof NavigationStart),
  switchMap(() => {
    // Cancel previous in-flight navigation
    return this.someService.cancelPending();
  })
).subscribe();

Quiz

1. Which router events bookend a successful navigation?

Question 1 options

2. How do you filter router events for a specific type?

Question 2 options

3. What is a practical use of router events?

Question 3 options

Flashcards

Question

Which events bookend navigation?

Answer

NavigationStart and NavigationEnd. Also NavigationCancel and NavigationError for failures.

Question

How do you filter router events?

Answer

filter(event => event instanceof NavigationEnd) — RxJS filter with instanceof.

Question

What are practical uses of router events?

Answer

Progress bars, analytics tracking, scroll-to-top, canceling in-flight navigations.

Revision Notes

Key Takeaways

  • 1. NavigationStart and NavigationEnd bookend transitions
  • 2. Filter events with RxJS filter + instanceof
  • 3. Progress bars use NavigationStart/End
  • 4. Analytics tracking uses NavigationEnd

Interview Tips

  • • Explain the router event lifecycle
  • • Be ready to describe practical event patterns
  • • Mention switchMap for canceling in-flight navigations

Cheat Sheet

Router Events Cheat Sheet

Event sequence:

NavigationStart → GuardsCheck → Resolve → NavigationEnd

Filter events:

this.router.events.pipe(
  filter((event): event is NavigationEnd => event instanceof NavigationEnd)
).subscribe(event => { ... });

Progress bar:

  • NavigationStart: show bar
  • NavigationEnd: hide bar

Analytics:

  • NavigationEnd: track page view

Continue Learning