Background
My team is working on an Angular application that has a long-running process - the details of this process are thoroughly unimportant to this question - that can be triggered from one of its screens. Because of the nature of this process, one of our business rules is that, once this process is triggered, we want to prevent our end-users from navigating away from the page to the best extent possible.
What we've tried
In our component, we've tried two approaches: @HostListener('window:unload')
event interception, and Angular's Router.events
interception. Neither has proven successful.
For the @HostListener()
approach, we implemented the following method in the body of the component, but as far as we could tell, it never actually fired, let alone stopped any navigation. It's also logical that it wouldn't, since window unload events would apply more to someone manually changing the window URL, or closing the current tab. It's probably a necessary part of implementing our business rule, for handling those specific cases.
@HostListener('window:beforeunload', ['$event'])
preventOffNavigation($event: any) {
// Do not stop off navigation if the special process isn't running.
if (!this.isProcessInProgress)
return $event.returnValue = true;
// ...Otherwise, disrupt the navigation.
$event.returnValue = false; // Could we also do something like $event.stopPropagation()?
}
The other thing is a little more mainstream - we subscribe to the Router.events
stream, and when we detect a NavigationStart
while the process is running, we...well, we don't actually know how we'd stop a navigation in process. When we inspected the event, there were no methods - it seemed purely informational. Under the .extras
property, there was a status property that we tried assigning NavigationCancel
, but that had precisely no effect.
constructor(
// Other imports aren't necessary for the context of this question
private router: Router
) {
this.router.events
.pipe(
filter(e => e instanceof NavigationStart
)
.subscribe((event: NavigationStart) => {
if (!this.isProcessInProgress)
return;
const currentNavigation = event.getCurrentNavigation();
if (!currentNavigation)
return;
// Didn't work, but worth a shot!
currentNavigation.extras.status = NavigationCancel;
});
}
Question
Our team really needs to keep our end users on a screen for our critical business process, but Angular doesn't provide a visible way to temporarily arrest navigation in its router system. Are we missing something? In what way can we prevent Angular from making router system navigations while our process is happening?