9. Component Router

Routes:

AppModule:

import { RouterModule, Routes } from '@angular/router';

const appRoutes: Routes = [
  { path: '**', component: WelcomeComponent } // <-- catchAll route
];

  imports: [
    BrowserModule,
    HttpModule,
    ReactiveFormsModule,
    FormsModule,
    RouterModule.forRoot(appRoutes)
  ]


AppComponent:

  <router-outlet></router-outlet>

routerLinks:

const appRoutes: Routes = [
  { path: 'article', component: ArticleComponent },
  { path: 'princess', component: PrincessComponent },
  { path: '**', component: WelcomeComponent }
];


          <h2>Root/Routing Component</h2>
          <a [routerLink]="''">Welcome</a>
          <a [routerLink]="'princess'">Princess</a>
          <a [routerLink]="'article'">Article</a>
          <router-outlet></router-outlet>

Router navigation:

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  template: `
      <div class="row">
      <h1>{{ title }}</h1>
        <div class="col-md-6">
          <h2>Root/Routing Component</h2>
          <button (click)="visitPrincess()">Princess</button>
          <button (click)="visitArticle()">Article</button>
          <router-outlet></router-outlet>
        </div>
        <div class="col-md-6">
            <app-princess></app-princess>
        </div>
      </div>
  `,
  styles: ['']
})
export class AppComponent {
  title = 'Angular 4 Love Affair';

  constructor(private router: Router) { }

  visitPrincess(): void {
    this.router.navigate(['princess']);
  }

  visitArticle(): void {
    this.router.navigate(['article']);
  }

}

LocationStrategy:

PathLocationStrategy: http://localhost:4200/princess
HashLocationStrategy: http://localhost:4200/#/princess

AppModule:
import { LocationStrategy, HashLocationStrategy, PathLocationStrategy } from '@angular/common';

providers: [AuthenticationService, PublishSubscribeService, APIService,
              {provide: LocationStrategy, useClass: HashLocationStrategy}]

routerLinkActive:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
      <div class="row">
      <h1>{{ title }}</h1>
        <div class="col-md-6">
          <h2>Root/Routing Component</h2>
          <a [routerLink]="''" [routerLinkActive]="'active-link'">Welcome</a>
          <a [routerLink]="'princess'" [routerLinkActive]="'active-link'">Princess</a>
          <a [routerLink]="'article'" [routerLinkActive]="'active-link'">Article</a>
          <router-outlet></router-outlet>
        </div>
        <div class="col-md-6">
            <app-princess></app-princess>
        </div>
      </div>
  `,
  styles: [`
    .active-link {
      color: red;
      text-transform: uppercase;
    }
    `]
})
export class AppComponent {
  title = 'Angular 4 Love Affair';

}

routerLinkActiveOptions:

<a [routerLink]="''" [routerLinkActive]="'active-link'" [routerLinkActiveOptions]="{exact: true}" >Welcome</a>
<a [routerLink]="'princess'" [routerLinkActive]="'active-link'" [routerLinkActiveOptions]="{exact: true}">Princess</a>
<a [routerLink]="'article'" [routerLinkActive]="'active-link'" [routerLinkActiveOptions]="{exact: true}">Article</a>
<router-outlet></router-outlet>

Nested views with route parameters and child routes

Parent component routing target for child views:

import { Component } from '@angular/core';

@Component({
  selector: 'app-article',
  template: `
      <h2>Article</h2>
      <router-outlet></router-outlet>
  `
})
export class ArticleComponent {

}

List and detail components:

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-article-list',
  template: `
      <h3>Article List</h3>
      <p *ngFor="let articleID of articleIDs">
        <a [routerLink]="articleID">
            Article {{ articleID }}
        </a>
      </p>
  `
})
export class ArticleListComponent {
      articleIDs: number[] = [100, 200, 300, 400, 500];

}

@Component({
  selector: 'app-article-detail',
  template: `
      <h3>Article Detail</h3>
      <p>Showing Angular article: {{ articleID }}</p>
      <a [routerLink]="'../'">Go Back</a>

  `
})
export class ArticleDetailComponent {
      articleID: number;

      constructor(private activatedRoute: ActivatedRoute) {
        activatedRoute.params.subscribe(params => this.articleID = params['articleID']);
      }
}

Child routes in AppModule:

const appRoutes: Routes = [
  { path: 'article', component: ArticleComponent, 
    children: [
      { path: '', component: ArticleListComponent },
      { path: ':articleID', component: ArticleDetailComponent}
    ]},
  { path: 'princess', component: PrincessComponent },
  { path: '**', component: WelcomeComponent }
];

Refactor detail component with async pipe:

@Component({
  selector: 'app-article-detail',
  template: `
      <h3>Article Detail</h3>
      <p>Showing Angular article: {{ ( activatedRoute.params | async ).articleID }}</p>
      <a [routerLink]="'../'">Go Back</a>

  `
})
export class ArticleDetailComponent {
      constructor(private activatedRoute: ActivatedRoute) { }
}

Another way: refer public observable interface and interpolate:

import { Component } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';

import {Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-article-detail',
  template: `
      <h3>Article Detail</h3>
      <p>Showing Angular article: {{ ( params | async ).articleID }}</p>
      <a [routerLink]="'../'">Go Back</a>
  `
})
export class ArticleDetailComponent {
      params: Observable<Params>;
      constructor(private activatedRoute: ActivatedRoute) {
        this.params = activatedRoute.params;
      }

}

Routing arrays && matrix URL parameters

<a [routerLink]="['article', {listData: 'ng4Rocks'}]" [routerLinkActive]="'active-link'" [routerLinkActiveOptions]="{exact: true}">Article</a>

Extract data from ActivatedRoute params:

@Component({
  selector: 'app-article-list',
  template: `
      <h3>Article List</h3>
      <p *ngFor="let articleID of articleIDs">
        <a [routerLink]="articleID">
            Article {{ articleID }}
        </a>
      </p>
  `
})
export class ArticleListComponent {
      articleIDs: number[] = [100, 200, 300, 400, 500];

      constructor(private activatedRoute: ActivatedRoute) {
          activatedRoute.params.subscribe(params => {
              console.log('List params:');
              console.log(window.location.href);
              console.log(params);
          });
      }
}

AuthenticationGuards

Routes:

const appRoutes: Routes = [
  { path: 'login', component: LogInComponent },
  { path: 'logout', component: LogOutComponent, canActivate: [ LogOutGuard ] },
  { path: 'profile', component: ProfileComponent, canActivate: [ AuthenticationGuard ] },
  { path: '**', component: WelcomeComponent }
];

Guards:

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthenticationService } from './authentication.service';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthenticationGuard implements CanActivate {

      constructor(private authenticationService: AuthenticationService,
                  private router: Router) { }

      canActivate(): Observable<boolean> {
        return this.authenticationService.userNameEmitter.map(userName => {
              if (!userName) {
                this.router.navigate(['login']);
              } else {
                return true;
              }
        }).take(1);
      }
}

@Injectable()
export class LogOutGuard implements CanActivate {

  constructor(private authenticationService: AuthenticationService,
              private router: Router) { }

  canActivate(): boolean {
      this.authenticationService.logout();
      this.router.navigate(['']);
      return true;
  }
}

LogInComponent:

import { Component, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { AuthenticationService } from '../authentication.service';

import { Subscription } from 'rxjs/Subscription';

@Component({
  selector: 'app-log-in',
  template: `
        <h2>LogIn View</h2>
        <input #userName>
        <button class="btn btn-success" (click)="logIn(userName.value)">LogIn</button>
  `
})
export class LogInComponent implements OnDestroy {
      private userNameSubscription: Subscription;
      constructor(private authenticationService: AuthenticationService,
                  private router: Router) { }

      logIn(newUserName: string): void {
        this.authenticationService.login(newUserName);
        this.userNameSubscription = this.authenticationService.userNameEmitter
                                  .subscribe(userName => {
                                    if (!!userName) {
                                      this.router.navigate[''];
                                    }
                                  });
       }

       ngOnDestroy() {
          this.userNameSubscription && this.userNameSubscription.unsubscribe();
       }

}

ProfileComponent:

import { Component } from '@angular/core';

import { AuthenticationService } from '../authentication.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-profile',
  template: `
            <div class="well">
              <h2>Profile View</h2>
              UserName: <input #uName value="{{ username | async }}">
              <button class="btn btn-danger" (click)="update(uName.value)">Update</button>
            </div>
  `
})
export class ProfileComponent {
       username: Observable<string>;

       constructor(private authenticationService: AuthenticationService) {
         this.username = authenticationService.userNameEmitter;
       }

       update(username: string): void {
         this.authenticationService.login(username);
       }

}

AppComponent:

import { Component } from '@angular/core';

import { AuthenticationService } from './authentication.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-root',
  template: `
      <div class="row">
      <h1>{{ title }}</h1>
        <div class="col-md-6">
          <h2>Root/Routing Component</h2>
          <h3 *ngIf="!!(userName | async)">
            Hello, {{ userName | async }}.
          </h3>
          <a [routerLink]="''" [routerLinkActive]="'active-link'" [routerLinkActiveOptions]="{exact: true}">Welcome</a>
          <a [routerLink]="'profile'" [routerLinkActive]="'active-link'" [routerLinkActiveOptions]="{exact: true}">Profile</a>
          <a *ngIf="!!(!userName | async )" [routerLink]="['login']">Login</a>
          <a *ngIf="!!(userName | async)" [routerLink]="['logout']">Logout</a>
          <router-outlet></router-outlet>
        </div>
        <div class="col-md-6">
            <app-princess></app-princess>
        </div>
      </div>
  `,
  styles: [`
    .active-link {
      color: red;
      text-transform: uppercase;
    }
    `]
})
export class AppComponent {
  title = 'Angular 4 Love Affair';
  userName: Observable<string>;

  constructor(private authenticationService: AuthenticationService) {
    this.userName = authenticationService.userNameEmitter;
  }


}

results matching ""

    No results matching ""