Angular for every one: Part 14
Use cases and how to
Often, we see examples of routing guards around the authentication but I find that too much reductive. Actually, it’s simply a control which allows or not to access to parts of the application.
There are several kinds of guards:
- CanActivate
- CanActivateChild
- CanDeactivate
- Resolve
- CanLoad
Use cases
So if it’s not to check if the user is authenticated then what’s for?
Roles
Well, beyond the authentication you can have to handle roles accesses. If your application is intended for operators and supervisors, probably supervisors can do more actions and can have access to more informations.
Fetching data
Maybe the target component requires data and it does not make sense to load it without this data. You should know that I have already written an article about this.
Using Angular Resolver to Pre Load Data
Save before leaving
You could have a workflow in your application which is a row of forms. You could need to save pending changes.
Discard or leave
Just a common case, the user has made some changes and click on a button without saving it. It could be nice in this case to check he is ok to discard his changes or not.
Defeat cunning devil
Some users can understand the routing system in place and that could be a problem. Imagine your workflow is based on routes and someone try to reach directly the second step which needs data from the first one… it could be a catastrophic user experience.
Guards in action
For all it’s the same logic, you have to choose the interface to implement. Here we will implement CanActivate guard.
interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
}
This is how to:
@Injectable({
providedIn: 'root',
})
_export class_ MyGuard _implements CanActivate_ {
_constructor_(/* everything you need */) {}
_public_ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
// Do your checks
}
}
What your guard should return? It depend of what you want to do but here’s some tips:
- If it returns an Observable, you have to know that the navigation will be blocked until it’s not complete.
- If it returns false, the navigation process stops and the user stays put.
- If you use router.navigate or router.navigateByUrl, you have to return true to continue the navigation process.
- You can return a UrlTree object to stop the current navigation and initialize a new one
Example of how to return a UrlTree:
_constructor_(private _router: Router) {}
_public_ canActivate(): boolean | UrlTree {
if (!myCondition) {
return this._router.parseUrl('/my-existing-route/in-my-app');
}
return true;
}
Conclusion
As you can see, Angular’s routing features provide a lot of possibilities and let you how to protect and manage the access of your routes. One more time, it responds to the principle of separation of concern. Of course you can do all of this directly inside your components. But it will less readable and understandable… Just don’t forget that if your guard returns false or nothing the navigation will be stopped. The usual, adapt the implementation of your solution from your need, not the other way around.
Thanks for reading.
Top comments (0)