Angular2 Routes – Controlling Access using Route Guards
Previously we discussed how we can use routing in an Angular2 app. This allows a user to navigate through the user interface.
In this post we are going to discuss how we can control access to these routes. These control work as guards to navigate in and away from the route.
Available Route Guards
There are a number of Route Guard types available for an Angular2 app. These are interfaces which can also be implemented by the same class. It just needs to implement the contract methods.
- CanActivate
- CanActivateChild()
- CanDeactivate
- Resolve
- CanLoad
What is the order of execution of these route guards?
An application can consist of various routes. There might also be route hierarchies if there are parent-child relationships between components. It must be remembered that route guards are executed bottom-up. So bottom child routes are executed before top routes are executed. It starts with CanDeactivate followed by CanActivateChild and CanActivate. CanLoad is executed when a module is loaded. What about Resolve??
Are they executed Synchronously / Asynchronously?
Route guards support both synchronous and asynchronous executions. It uses rxJS for asynchronus execution. For synchronous execution, the guard just returns true or false. In the asynchronous case, it returns Observable<Boolean> instead. If you are wondering why we need asynchronous execution for routes at all, consider the case when you might need to display a message to user and get a confirmation before exiting to confirm the possible lost changes. Or you might need a service call before a guard is satisfied.
Guards aren’t democratic
Guards are not democratic. It’s not sufficient to satisfy most routes. All routes should eventually return true before a route can be activated.
Example Scenario – Chat Service
Let’s use the example repository from our existing Angular2 Routes repository from one of our previous discussion. Let’s add a component for chat. Since our service representatives are only available during the working hours of 9:00 AM to 5:00 PM, we only want the chat page to be available during that time duration. We also want to show some message as they are leaving the page to thank their interaction with our service agents.
Creating the Component
Let’s first create chat component using Angular2 CLI.
Adding chat component to Route Config
Now let’s add chat component to RouteConfig. This is defined in app.module.ts. Here we are using “/chat” as sub-route for our chat page.
Now as we use the configured route, we are shown with this amazing message that we defined in chat.component.html page. You might not have seen the same message before but that’s a general intention of all customer services. And isn’t the intention that counts…
CanActivate Route Guard
Let’s create a CanActivate route guard. This checks the current time. If the current time falls between 9:00 AM and 5:00 PM, the page is displayed.
We need to define CanActivate route. Obviously this would implement CanActivate interface. If you are coming from C# or Java background, the implementation might seem a little strange to you. Actually the same method might return either of a list of return type here. Here you can see that the method returns boolean | Observable<boolean> | Promise<boolean>
The other interesting piece is string interpolation in console.log(). Other languages do support interpolation now including C#. But this is interesting that typescript also supports this. We need to use back-tick for interpolating variables in scope.
console.log(`Is Chat allowed: ${isAllowed}`)
And this is how it is displayed. Since we are accessing this during the working hours of our chat agents, the page is navigated properly. You can also notice the message logged in the console.
CanDeactivate Route Guard
Let’s show a message to the user as they are leaving our page. We don’t want to keep them on our component, we just want to show them, we care… That’s why we are just showing them in the console log.
Here we are just showing the message and returning true.
We need to add this guard to the component. We also need to add this in the providers array.
Now as we navigate away from the component, the message is displayed in the console. In order to show it is working, we have added some router links to our app.component.html to using hyperlinks for navigation.
Github Repository: