Is it possible to stop router navigation based on some condition
AngularAngular Problem Overview
I'm new to angular, I want stop the routing when user clicks on refresh button or back button based on some condition. I don't know whether this is possible, if anybody knows help me
constructor(private route: Router) {
this.route.events
.filter(event => event instanceof NavigationEnd)
.pairwise().subscribe((event) => {
if (expression === true){
// stop routing
} else {
// continue routing
}
});
}
Can it be possible? If yes, how can I do this?
Angular Solutions
Solution 1 - Angular
I stumbled upon this question quite a bit after the fact, but I hope to help someone else coming here.
The principal candidate for a solution is a route guard.
See here for an explanation: https://angular.io/guide/router#candeactivate-handling-unsaved-changes
The relevant part (copied almost verbatim) is this implementation:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
import { MyComponent} from './my-component/my-component.component';
@Injectable({ providedIn: 'root' })
export class CanDeactivateGuard implements CanDeactivate<MyComponent> {
canDeactivate(
component: MyComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | boolean {
// you can just return true or false synchronously
if (expression === true) {
return true;
}
// or, you can also handle the guard asynchronously, e.g.
// asking the user for confirmation.
return component.dialogService.confirm('Discard changes?');
}
}
Where MyComponent
is your custom component and CanDeactivateGuard
is going to be registered in your AppModule
in the providers section and, more importantly, in your routing config in the canDeactivate
array property:
{
path: 'somePath',
component: MyComponent,
canDeactivate: [CanDeactivateGuard]
},
Solution 2 - Angular
The easy way for me is with skiplocationchange in a new route navigate like this:
if(condition === true){
const currentRoute = this.router.routerState;
this.router.navigateByUrl(currentRoute.snapshot.url, { skipLocationChange: true });
// this try to go to currentRoute.url but don't change the location.
}else{
// do nothing;
}
is a no beautiful method but works
Solution 3 - Angular
There is another solution which I invented and it works:
(For lazy people like me who do not want to create guard for handling this)
import { NavigationStart, Router } from '@angular/router';
In constructor:
constructor(private router: Router) {
router.events.forEach((event) => {
if (event instanceof NavigationStart) {
/* write your own condition here */
if(condition){
this.router.navigate(['/my-current-route']);
}
}
});
}
Hopefully you won't be lazy enough to change '/my-current-route'
to your route url.
Solution 4 - Angular
You can use NavigationStart event like the following code snippet.
this.router.events.subscribe( (event: any) => {
if (event instanceOf NavigationStart) {
/// Your Logic
}
})