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.