Best & simple Steps to understand Angular 2 Routing

The Angular 2 router is strictly connected to the component. It’s also called the Component Router (which is about to come to Angular 1.x as well). The main purpose of it is to have routable components. They are often smart components that are fetching resources from the API.

Configuration

Let’s start with adding a router to the app. The very beginning is to add the general URL to that app which is accessible. This usually ends up with / as the entrance point, but you may need to change it such as when you are trying to connect Angular 2 with an existing app.

The base href is achieved by adding the element base (in index.html):

<base href="/">

This is the only step you have to make in HTML. Next it’s time to configure providers. We move to the place where the app is being bootstrapped and import ROUTER_PROVIDERS:

import { bootstrap } from [email protected]/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from [email protected]/router';

import { AppComponent } from './app.component';

bootstrap(AppComponent, [
  ROUTER_PROVIDERS
]);

This way we are able to inject router providers anywhere in the app and they will be singletons.

Router Outlet

Now it’s time to add the first routable component. First of all, let’s recap the most basic component that App could be:

import { Component } from [email protected]/core';

@Component({
  selector: 'app',
  template: 'Hello App'
})
class AppComponent {};

To add some routes we can start with their definitions:

import { Component } from [email protected]/core';
import { Routes } from [email protected]/router';
import { LoginComponent } from './pages/login/login.component';
import { SignupComponent } from './pages/signup/signup.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { UserStoreService } from './common/services/userStore.service';
import { HomeComponent } from './pages/home/home.component';

@Component({
  selector: 'app',
  template: 'Hello App'
})
@Routes([
  { path: '/', component: HomeComponent },
  { path: '/login', component: LoginComponent },
  { path: '/signup', component: SignupComponent },
  { path: '/dashboard', component: DashboardComponent },

  // Catch route
  { path: '*', component: HomeComponent }   
])
class AppComponent {};

Now we do have configuration for this particular component, but routes won’t be visible. It’s happening because of the lack of a place where the router should render its content. So we’re importing ROUTER_DIRECTIVES:

import { ROUTER_DIRECTIVES, Routes } from [email protected]/router';
...

@Component({
  selector: 'app',
  directives: ROUTER_DIRECTIVES,
  template: `
    <router-outlet></router-outlet>
  `
})
...

This time, instead of a simple string, we’re using RouterOutlet to make a placeholder for routable components. If you change the URL to match some path it should render the proper component.

Router Link

It works perfectly but lacks a very important feature – links to other routes. This one is achieved by the RouterLink directive. With the appropriate parameters it can route to named routes. Look at the template:

import { Component } from [email protected]/core';
import { ROUTER_DIRECTIVES, Routes } from [email protected]/router';
import { LoginComponent } from './pages/login/login.component';
import { SignupComponent } from './pages/signup/signup.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { UserStoreService } from './common/services/userStore.service';
import { HomeComponent } from './pages/home/home.component';

@Component({
  selector: 'app',
  directives: ROUTER_DIRECTIVES,
  template: `
    <nav>
      <ul>
        <li><a [routerLink]="['/home']">Home</a></li>
        <li><a [routerLink]="['/dashboard']">Dashboard</a></li>
        <li><a [routerLink]="['/login']">Log In</a></li>
        <li><a [routerLink]="['/signup']">Sign Up</a></li>
      </ul>
    </nav>
    <router-outlet></router-outlet>
  `
})
@Routes([
  { path: '/', component: HomeComponent },
  { path: '/login', component: LoginComponent },
  { path: '/signup', component: SignupComponent },
  { path: '/dashboard', component: DashboardComponent },

  // Catch route
  { path: '*', component: HomeComponent }   
])
class AppComponent {};

The configuration and code up to this point should give a working rout to the proper components basing on the routing table provided for the component.

Route Parameters

We’re able to route to the static URL path, but now it’s time to make it more dynamic. The first thing you meet when trying to solve real problems is to add a dynamic id to the URL. It’s quite easy in Angular 2. Let’s consider following the dashboard component:

@Component({
    selector: 'dashboard',
    template: `
      <router-outlet></router-outlet>      
      <a [routerLink]="['./', 'room1']">Go to room1</a>
    `.
    directives: ROUTER_DIRECTIVES
})
@Routes([
    { path: '/', component: DashboardMainComponent },
    { path: '/:name', component: RoomComponent },

    // Catch All route
    { path: '*', component: DashboardMainComponent }
])

In the routes you’ll see:

{ path: '/:name', component: RoomComponent },

It indicates a path with a parameter. This path can be supplied either by entering with the proper URL, or by adding a router link with a second parameter in the array:

<a [routerLink]="['./', 'room1']">Go to room1</a>

The router link gets a DSL path as the first item in the array. It can be either absolute or relative. The second one is part of the URL. In our case it passes the name to the component, which is accessible by /:name. The first is the map of query string parameters.

Lifecycle hooks

On the other hand, in the component we just routed to it would be nice to get the params there. Like Angular component hooks, the router adds its own. Angular fires the onInit hook when it initializes the component. In the same way we can implement router interfaces inside the class that has the @Routes annotation. We are able to use following hooks:

  • OnActivate – fired upon a successfully activated route
  • CanDeactivate – defines whether a component can be deactivated

The one that is especially useful here is OnActivate. It let’s you define code that has to be invoked right after successful redirection. Moreover, it gives us information about current and previous routes. We’ll incorporate that in the following manner:

import {
  OnActivate,
  Router,
  RouteSegment,
  RouteTree
} from [email protected]/router';
...

class RoomComponent implements OnActivate {
  private selectedName: number;

  routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree, prevTree?: RouteTree): void {
    this.selectedName = curr.getParam('name');
  }
}

Now we were able to get the param passed by the URL directly to the code.

About the author

Deven Rathore

Deven Rathore

I'm Deven Rathore, a multidisciplinary & self-taught designer with 3 years of experience. I'm passionate about technology, music, coffee, traveling and everything visually stimulating. Constantly learning and experiencing new things.

  • So, I decided to take a look – out of curiosity – at what is going on with modern tech lol, and seems like about a dozen years passed with zero evolution since last time I was using similar things. Sad planet !

    • Deven Rathore

      SAD PLANET > SAD SOLAR SYSTEM > SAD GALAXY > SAD UNIVERSE and sad Programmer 😉

Pin It on Pinterest

Shares