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
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!