When the first release candidate came out, the team behind Angular released a reworked router and deprecated the old one. With the second release candidate they reworked it again (to solve numerous existing problems) incorporating feedback from the previous one and released it as version 3.0. At the same time they started to encourage people to use and test it to get more feedback.
In this tutorial I’ll show you how to upgrade from the deprecated router (@angular/router-deprecated) to version 3.0 . The inner workings of the new router won’t be described in detail. If you are interested, you can get your head around it easily from the updated official documentation, Viktor Savkin’s detailed blog post or the article on Thoughtram.
In our example we are having a main route with a list of items and another route which shows the details of an item like in the Tour of Heroes tutorial.
Let’s look at our old router configuration described with a decorator on the main component.
We define two routes, Heroes for the default route and HeroDetail for displaying the details of a hero. We have to add a unique name to each route, which is used to address them when displaying links or redirecting.
The big change with the new router is that routing configuration is no longer bound to a specific component, instead it is accessible as a provider.
When defining the new routes only two things need to be removed from the definition. The first one is the leading slash from the path property, the second one is the name property. From now on we will use the path as an identifier. We need to feed our new APP_ROUTER_PROVIDER to the application and replace the existing ROUTER_PROVIDERS imported from the deprecated package.
This setup will become:
The active route is placed inside the RouterOutlet element. It’s markup and setup won’t change. We only have to import it from the new package.
Now we can safely delete the @RouteConfig decorator from our AppComponent.
Linking to routes
The old way routes were identified by their names and you could pass values to the placeholders with object literals.
With the new router they are identified by their path and you have to skip the placeholder.
This parameter transformation also affects the navigate method of the Router service.
Route parameter access
On the HeroDetail route we need to access the identifier for the hero to be able to fetch it from a service. Parameter access was pretty straightforward with RouteParams as it held the parameters and could give them back through a getter method.
Now RouteParams is replaced by ActivatedRoute. The key difference is that route parameters can be accessed through the params property as an Observable. The values in the Observable are objects with properties named after the route parameters.
When it comes to authentication we want to guard the components that are restricted from unauthenticated users. The old router gave a solution for this with lifecycle decorators (@CanActivate, @CanDeactivate).
The guarding logic could be put inside a callback function.
It had several drawbacks. The biggest is that it didn’t have access to the application’s dependency injection. The second one is that you had to decorate every Component class with it what you wanted to guard. If you want to read more about authentication with the deprecated router read this article.
With the new router these problems solved. It has access to dependency injection, it is defined inside the route configuration and can be chainable.
We can easily inject the AuthService and even the Router with which we can redirect the user to the login screen. The next step is to setup this guard on the route configuration.
The property canActivate holds the guards as an array. This is the way they become chainable also.
With these little steps we managed to migrate our application from the deprecated router to the new one (version 3.0).
The parts we touched are
- route configuration and setup
- linking to routes in template and code
- accessing route parameters
- guarding routes from unauthenticated users