I am using CanDeactivateGuard in my Angular application where i have handled the browser back button using location.onPopState to show an alert.
But when i click the browser button first and cancel the alert box which is shown and click the browser button it doesn't shows the alert back when i put logs for the location.onPopState it calls the location.onPopState but it doesn't calls the canDeactivateGuard
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
backButtonClicked = false;
constructor(public location: LocationStrategy) {
location.onPopState(() => {
console.log('location popstate got called', location);
this.backButtonClicked = true;
});
}
canDeactivate(component: CanComponentDeactivate) {
console.log('canDeactive called', this.backButtonClicked);
if (this.backButtonClicked) {
this.backButtonClicked = false;
history.pushState(null, null, location.href);
}
return component.canDeactivate ? component.canDeactivate() : true;
}
}
I have used a custom navigation service which listens for the router events but when the location.onPopState is called and then the canDeactivate is not triggered then at the same time the router events are also not called.
@Injectable({ providedIn: 'root' })
export class NavigationService {
private history: string[] = [];
private goingBack = false;
constructor(private router: Router, private location: Location) {
this.router.events.subscribe((event) => {
console.log('event is', event);
if (event instanceof NavigationStart && event.navigationTrigger === 'popstate') {
this.back();
} else if (event instanceof NavigationCancel) {
this.goingBack = false;
console.log('history in cancel', this.history);
} else if (event instanceof NavigationEnd) {
this.historyPop(event);
}
});
}
historyPop(event): void {
console.log('event in history pop is', event);
if (this.goingBack) {
this.history.pop();
this.history.pop();
}
this.goingBack = false;
this.history.push(event.urlAfterRedirects);
console.log('history is', this.history);
}
back(): void {
const urlToback = this.history[this.history.length - 2];
this.goingBack = true;
if (urlToback) {
this.router.navigateByUrl(urlToback);
} else {
this.router.navigateByUrl('/');
}
console.log('history in back is', this.history);
}
replaceState(url: string): void {
this.history[this.history.length - 1] = url;
this.location.replaceState(url);
}
}