When my users have dirty changes on a screen, I have a route guard to prompt them to save or discard when they try to navigate away.
However, if I am logging them out due to inactivity, I want to force navigation and bypass the route guard (by discarding their changes), in order to ensure that their screen is blanked.
How can I bypass route guards?
CanDeactivate is a TypeScript interface that needs to be implemented by a component to create a route guard. This guard will be used by the router to decide if the route can be deactivated. It can be implemented in any Angular component using the canDeactivate method of the interface.
This route guard is used to keep the user from navigating away from a specific route. This guard can be useful when you want to prevent a user from accidentally navigating away without saving or some other undone tasks.
CanActivateChild - Decides if children routes of a route can be activated. CanDeactivate - Decides if a route can be deactivated.
The Angular router's navigation guards allow to grant or remove access to certain parts of the navigation. Another route guard, the CanDeactivate guard, even allows you to prevent a user from accidentally leaving a component with unsaved changes.
My solution was as follows:
My logout
method after successfully logging out, redirects the app to the /login
route:
@Injectable
export class AuthService {
// ...
logout () {
// do logout
this.router.navigate(['/login']);
}
}
My guard is then as follows:
@Injectable
export class DiscardChangesGuard implements CanDeactivate<MyComponent> {
canDeactivate(component: MyComponent, currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Observable<boolean> | boolean {
if (nextState.url === '/login') {
return true; // bypass checks if we are trying to go to /login
}
// perform regular checks here
}
}
Here's how you can force a bypass on a per-navigation basis. In my case I was navigating back to the account dashboard after the user submits a form with account info.
Ideally you would check for unsaved changes in the form and bypass based on that, but my forms don't have that feature yet.
form component:
this.router.navigateByUrl('/', { state: { bypassFormGuard: true } })
router guard:
@Injectable()
export class ExitFormGuard implements CanDeactivate<ComponentCanDeactivate> {
constructor(private router: Router) {}
canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
if (this.router.getCurrentNavigation()?.extras?.state?.bypassFormGuard) {
return true
}
// perform normal checks
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With