Route guards - AngularBuildUp/angular-microworkshops-authorization GitHub Wiki
Route guards
Route guards can be used to validate some router URL's. For example, you may have some URL's that would result in a 404. In order to detect that you need a route guard.
A route guard can be a function or a service. If it is a service, then it needs to implement the Angular CanActivate
interface. This interface has a method, canActivate(route:ActivatedRouterSnapshot)
which resolves the current router parameters passed for this particular route. This method returns a boolean
. If it's return value false
, it means you cannot activate this page and you need to redirect to a different one, through this method's code.
Example (with service)
export class MyRouterActivator implements CanActivate {
// constructor here
canActivate (route: ActivatedRouterSnapshot) {
let exists = routeWithParamsExists(+route.params["id"]);
if(!exists) {
this.router.navigate(["/404"]);
}
return exists;
}
}
If the route does not exist, then it makes the router to redirect to /404
(which is a registered route with a component), else it proceeds as normal.
To make it work with the router registration, use the canActivate
property on Route
.
export const routes: Router[] = [
{ path: "/mypath/:id", component: MyComponent, canActivate: [MyRouterActivator] }
];
Deactivation
Same way we can guard against a component's activation, we can guard against a component's deactivation. This means that the router will prevent you from navigating to another route, until the value in the deactivate
event is true
.
Same fashion, you can define a service or a function to control the deactivate state of a component. Let's see how it is to have a function.
You use the canDeactivate
property on a Route
.
{ path: "/mypath/:id", component: MyComponent, canDeactivate: ["canDeactivateGuard"] }
We use a function here, so we can pass a string
, or an OpaqueToken
. This is used to resolve the registered item in dependency injection container.
Now we have to register this particular function:
providers: [
{ provider: "canDeactivateGuard", useValue: checkDirtyState }
]
The checkDirtyState
is a function.
The very first parameter that is passed into the canDeactivate
function is the current component
function checkDirtyState(component: MyComponent): boolean {
// code here
}
Now, you should have some sort of public API in the MyComponent
component to check for some specific state and validate against the canDeactivate
function. If your return value is false
, the it is prohibited to navigate away from this particular route.