I have written code to handle browser navigation using the router, but I’m experiencing an issue where navigation is already happening before my custom confirmation dialog opens. Can anyone suggest a solution to stay on same page?”
Navigation service
import { Injectable } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Location } from '@angular/common';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class NavigationService {
private internalNavigation = false;
//private previousUrl: string | null = null;
private navigationEventSource = new Subject<string>();
navigationEvent$ = this.navigationEventSource.asObservable();
constructor(private router: Router, private location: Location) {
console.log("Navigation service called>>>");
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
//const currentUrl = event.url;
if (event.navigationTrigger === 'popstate') {
console.log("Navigation service called with pop state>>>");
if (this.internalNavigation) {
this.navigationEventSource.next('internal');
this.internalNavigation = false;
} else {
this.navigationEventSource.next('browser');
// Push dummy state to history to prevent actual back navigation
//history.pushState(null, '');
}
} else {
this.navigationEventSource.next('internal');
}
//this.previousUrl = currentUrl;
}
});
// Push initial dummy state to history
//history.pushState(null, '');
}
goBack(): void {
this.internalNavigation = true;
this.location.back();
}
}
app.component.ts
ngOnInit() {
// Prevent browser back button navigation
history.pushState(null, '');
this.navigationSubscription = this.navigationService.navigationEvent$.pipe(
takeUntil(this.unsubscriber)
).subscribe(event => {
if (event === 'internal') {
// Handle internal navigation logic here
} else if (event === 'browser') {
this.userSubscription = this.userProviderService.getUserDetails()
.pipe(takeUntil(this.destroy$))
.subscribe((userDetails: UserSessionObject | null) => {
if (userDetails && userDetails.user) {
this.sessionLogout("BackButtonTap");
if (!this.isDialogOpen) {
this.openBackButtonDialog();
}
}
});
}
});
}
custom dialog
openBackButtonDialog = () => {
this.isDialogOpen = true;
this.backRef = this.dialogService.open(this.backButtonDialogTemplate, {
context: '',
hasBackdrop: true,
closeOnBackdropClick: false,
closeOnEsc: false
});
this.backRef.onClose.subscribe((result) => {
//handling the confirm dialog opening immedialtely after close
this.isDialogOpen = true;
setTimeout(() => {
this.isDialogOpen = false;
}, 500);
if(result) {
history.pushState(null, '');
this.sessionLogout("BackButtonTap"); //logged out the session
} else {
history.forward(); //stay on the same page
}
});
}