Published: November 24 2022

Angular - Detect Route Change (Location Change) Event in Angular

Tutorial built with Angular 14.2.11

This is a super quick post to show how to detect and execute code on route change (location change) in Angular.

The example code is from a Angular alerts tutorial I posted recently which automatically clears alerts on location change. For the full alerts tutorial see Angular 14 - Alert (Toaster) Notifications Tutorial & Example.


Subscribe to the NavigationStart Router Event

Cutting to the chase, this is the snippet used to subscribe to router events and then execute code on NavigationStart:

 ngOnInit() { // clear alerts on location change this.routeSubscription = this.router.events.subscribe(event => { if (event instanceof NavigationStart) { this.alertService.clear(this.id); } }); }


The router.events property is an RxJS Observable that emits router lifecycle events to subscribers each time the route is changed in Angular. NavigationStart is the first of a sequence of events that are emitted, there are many others including NavigationEnd, NavigationCancel, NavigationError and more. For a full list and the order they are executed see https://angular.io/api/router/Event.


Don't Forget to Unscubscribe on Destroy

This snippet unsubscribes from the route change subscription when the component is destroyed to dispose the resources held by the subscription and avoid memory leaks in the Angular app.

 ngOnDestroy() { // unsubscribe to avoid memory leaks this.routeSubscription.unsubscribe(); }


Complete Angular Alert Component

Below is the complete alert component that subcribes to route changes in the ngOnInit method and unsubscribes in the ngOnDestroy() method.

The rest of the code controls the display of alerts in the UI, for more info and a live demo see Angular 14 - Alert (Toaster) Notifications Tutorial & Example.

 import { Component, OnInit, OnDestroy, Input } from '@angular/core'; import { Router, NavigationStart } from '@angular/router'; import { Subscription } from 'rxjs'; import { Alert, AlertType } from './alert.model'; import { AlertService } from './alert.service'; @Component({ selector: 'alert', templateUrl: 'alert.component.html' }) export class AlertComponent implements OnInit, OnDestroy { @Input() id = 'default-alert'; @Input() fade = true; alerts: Alert[] = []; alertSubscription!: Subscription; routeSubscription!: Subscription; constructor(private router: Router, private alertService: AlertService) { } ngOnInit() { // subscribe to new alert notifications this.alertSubscription = this.alertService.onAlert(this.id) .subscribe(alert => { // clear alerts when an empty alert is received if (!alert.message) { // filter out alerts without 'keepAfterRouteChange' flag this.alerts = this.alerts.filter(x => x.keepAfterRouteChange); // remove 'keepAfterRouteChange' flag on the rest this.alerts.forEach(x => delete x.keepAfterRouteChange); return; } // add alert to array this.alerts.push(alert); // auto close alert if required if (alert.autoClose) { setTimeout(() => this.removeAlert(alert), 3000); } }); // clear alerts on location change this.routeSubscription = this.router.events.subscribe(event => { if (event instanceof NavigationStart) { this.alertService.clear(this.id); } }); } ngOnDestroy() { // unsubscribe to avoid memory leaks this.alertSubscription.unsubscribe(); this.routeSubscription.unsubscribe(); } removeAlert(alert: Alert) { // check if already removed to prevent error on auto close if (!this.alerts.includes(alert)) return; // fade out alert if this.fade === true const timeout = this.fade ? 250 : 0; alert.fade = this.fade; setTimeout(() => { // filter alert out of array this.alerts = this.alerts.filter(x => x !== alert); }, timeout); } cssClass(alert: Alert) { if (!alert) return; const classes = ['alert', 'alert-dismissible']; const alertTypeClass = { [AlertType.Success]: 'alert-success', [AlertType.Error]: 'alert-danger', [AlertType.Info]: 'alert-info', [AlertType.Warning]: 'alert-warning' } if (alert.type !== undefined) { classes.push(alertTypeClass[alert.type]); } if (alert.fade) { classes.push('fade'); } return classes.join(' '); } }

 


Need Some Angular Help?

Search fiverr for freelance Angular developers.


Follow me for updates

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by