import { Injectable, OnDestroy } from '@angular/core'; import { CanActivate, NavigationEnd, NavigationStart, Router, } from '@angular/router'; import { Subscription } from 'rxjs'; import { filter, pairwise, } from 'rxjs/operators'; @Injectable() export class DebounceNavigationService implements CanActivate, OnDestroy { navigationStartSub: Subscription; navigationSuccessSub: Subscription; private lastNavigation: NavigationStart; private thisNavigation: NavigationStart; private lastNavigationSuccessId: number; constructor(private router: Router) { this.navigationStartSub = this.router.events .pipe(filter(event => event instanceof NavigationStart), pairwise()) .subscribe((events: [NavigationStart, NavigationStart]) => [this.lastNavigation, this.thisNavigation] = events); this.navigationSuccessSub = this.router.events .pipe(filter(event => event instanceof NavigationEnd)) .subscribe((event: NavigationEnd) => this.lastNavigationSuccessId = event.id); } async canActivate() { return !(this.thisNavigation?.navigationTrigger === 'hashchange' && this.lastNavigation.navigationTrigger === 'popstate' && this.lastNavigationSuccessId === this.lastNavigation.id && this.lastNavigation.url === this.thisNavigation?.url); } ngOnDestroy() { if (this.navigationStartSub != null) { this.navigationStartSub.unsubscribe(); } if (this.navigationSuccessSub != null) { this.navigationSuccessSub.unsubscribe(); } } }