Angular 2 Tutorial : Understanding Angular 2 Routing

Angular 2 Tutorial : Understanding Angular 2 Routing

  • 2016-08-27
  • 3281

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

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

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

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

bootstrap(AppComponent, [
  ROUTER_PROVIDERS
]);

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.

READ Angular 2 Tutorial : GuildRunner sandbox Angular 2 application

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

Lifecycle hooks

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');
  }
}

Source via: dunebook.com

Suggest

Angular 2 and NodeJS - The Practical Guide to MEAN Stack 2.0

Learn Angular 2 Development By Building 10 Apps

Angular 2 - Superheroic Framework

Angular 2 Crash Course with TypeScript

Angular 2 - The Complete Guide (Updated to RC4!)