Angular 6 Routing/Navigation – with Angular Router Service

Angular 6 Routing_Navigation – with Angular Router Service

In Angular application, how to navigation among views? Developers can achieve it with the power of Angular Router Service that helps find out a corresponding Route when having any changes of browser’s URL to determine the component to display.

Related posts:
Integrate Bootstrap with Angular
Angular 6 Service – with Observable Data for Asynchronous Operation
Angular 6 Component – How to create & integrate New Angular 6 Component
Angular 6 dynamic Navigation Bar – add/remove Route dynamically

Technologies

  • Node.js – version v10.4.0
  • Angular – version 6
  • Bootstrap – 3.x & 4.x
  • Visual Studio Code – version 1.24.0

Goal

We create an Angular project as below:

angular-6-routing + angular-project-structure

-> Navigation:

– Home Page (also US Customer Component page):

– UK Customer Component page:

angular-6-routing + uk - customer

– Details Customer page:

angular-6-routing + a-customer-view-routing

– Press go Back button:

angular-6-routing + go back

Application provides a list URLs as below:

  • http://localhost:4200/
  • http://localhost:4200/customers-us
  • http://localhost:4200/customers-uk
  • http://localhost:4200/customers/:id

How to navigate among these views?

– When enter in browser address bar: http://localhost:4200 or http://localhost:4200/customers-us, the app will always redirect to http://localhost:4200/customers-us that be served by CustomerUSComponent.
– When click on each customer item’s link in CustomerUsComponent or CustomerUkComponent views, or enter the links http://localhost:4200/customers/:id in browser address bar -> The browser will show CustomerDetailComponent view with the Browser’s URL http://localhost:4200/customers/{id}.
– Press on Back button, the browser’s URL will be backed one step.

When press other URLs, PageNotFound will be appeared:

angular-6-routing + wrong-url

Angular Router

Angular project preparation

– Generate Angular project:

angular-6-routing + create-angular-project

– Generate:

  • 4 Components {CustomerUsComponent, CustomerUkComponent, CustomerDetailComponent, PageNotFoundComponent}
  • Data Service: CustomerService
  • Module: AppRoutingModule
  • Class: Customer

angular-6-routing + create-angular-generate-components-service-app-routing

– Install Bootstrap 4:

npm install bootstrap jquery --save

-> Configure installed Bootstrap & JQuery in angular.json file:

...
 
"styles": [
  "src/styles.css",
  "node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
  "node_modules/jquery/dist/jquery.min.js",
  "node_modules/bootstrap/dist/js/bootstrap.min.js"
]
 
...
Angular Router
Angular Routing Module

In the AppRoutingModule file, configure routes as below:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

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

import { CustomerUsComponent } from '../customer-us/customer-us.component';
import { CustomerUkComponent } from '../customer-uk/customer-uk.component';
import { CustomerDetailComponent } from '../customer-detail/customer-detail.component';
import { PageNotFoundComponent } from '../page-not-found/page-not-found.component'

const routes: Routes = [
  { 
    path: 'customers-us', 
    component: CustomerUsComponent 
  },
  { 
    path: 'customers-uk', 
    component: CustomerUkComponent 
  },
  { 
    path: 'customers/:id',
    component: CustomerDetailComponent 
  },
  { 
    path: '',
    redirectTo: '/customers-us',
    pathMatch: 'full'
  },
  { 
    path: '**',
    component: PageNotFoundComponent 
  }
];

@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule { }

routes array of routes describes how to navigate.
– Each Route maps a URL path to a component.
– The :id in the second route is a token for a route parameter.

Register AppRoutingModule with AppModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { CustomerUsComponent } from './customer-us/customer-us.component';
import { CustomerUkComponent } from './customer-uk/customer-uk.component';
import { CustomerDetailComponent } from './customer-detail/customer-detail.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { AppRoutingModule } from './app-routing/app-routing.module';

@NgModule({
  declarations: [
    AppComponent,
    CustomerUsComponent,
    CustomerUkComponent,
    CustomerDetailComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Router Outlet & Router Links

Questions:

  • How to show Componenets with Angular Routers? -> Solution: using Router Outlet
  • How to handle the routing that comes from user’s actions? (like clicks on anchor tag) -> Solution: using Router Link

-> We can achieve above functions by using Angular’s router-outlet and routerLink.

Now modify the template file app.component.html of parent AppComponenet component as below:

Angular Router


The RouterLinkActive directive is used to visual the anchor tag for the currently selected “active” route.
Now these components {CustomerUsComponent, CustomerUKComponent, CustomerDetailComponent, PageNotFoundComponent} will be showed under router-outlet tag.

We already had done to setup Routing configuration. -> It’s time for developement Data Service & view-Components.

Data Services implementation
Customer Data Model

Code for customer.ts class:

export class Customer {
    constructor(public id: number, 
                public firstname: string, 
                public lastname:string,
                public nationality: string) { }
}
Customer Service
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';

import { Customer } from './customer'
import { filterQueryId } from '@angular/core/src/view/util';

const CUSTOMERS = [
  {id: 1, firstname: 'Mary', lastname: 'Taylor', age: 24, nationality: 'US'},
  {id: 2, firstname: 'Peter', lastname: 'Smith', age: 18, nationality: 'UK'},
  {id: 3, firstname: 'Lauren', lastname: 'Taylor', age: 31, nationality: 'UK'},
  {id: 4, firstname: 'Michael', lastname: 'Brown', age: 45, nationality: 'US'},
  {id: 5, firstname: 'David', lastname: 'Moore', age: 25, nationality: 'US'},
  {id: 6, firstname: 'Holly', lastname: 'Davies', age: 27, nationality: 'UK'},
  {id: 7, firstname: 'Joe', lastname: 'Thomas', age: 36, nationality: 'UK'},
];


@Injectable({
  providedIn: 'root'
})
export class CustomerService {

  constructor() { }
}

@Injectable()
export class HeroService {
  getCustomers() { return of(CUSTOMERS); }

  getCustomer(id: number | string) {
    return this.getCustomers().pipe(
      // (+) before `id` turns the string into a number
      map(customers => customers.find(customer => customer.id === +id))
    );
  }

  getCustomersByNationality(nationality: string){
    return this.getCustomers().pipe(
      map(customers => customers.filter(cust => cust.nationality === nationality))
    )
  }
}
Angular Components implementation
Customer US Component

– Implement customer-us.component.ts class:

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

import { Observable } from 'rxjs';

import { Customer } from '../customer'
import { CustomerService} from '../customer.service'

@Component({
  selector: 'app-customer-us',
  templateUrl: './customer-us.component.html',
  styleUrls: ['./customer-us.component.css']
})
export class CustomerUsComponent implements OnInit {

  customers$: Observable;

  constructor(private service: CustomerService) { }

  ngOnInit() {
      this.customers$ = this.service.getCustomersByNationality('US');
  }
}

Implement CustomerUSComponent template file customer-us.component.html:


Customer UK Component

– Implement CustomerUkComponent class in file customer-uk.component.ts:

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

import { Observable } from 'rxjs';

import { Customer } from '../customer'
import { CustomerService} from '../customer.service'

@Component({
  selector: 'app-customer-uk',
  templateUrl: './customer-uk.component.html',
  styleUrls: ['./customer-uk.component.css']
})
export class CustomerUkComponent implements OnInit {

  customers$: Observable;

  constructor(private service: CustomerService) { }

  ngOnInit() {
      this.customers$ = this.service.getCustomersByNationality('UK');
  }

}

– Implement CustomerUkComponent template file customer-uk.component.html :


Customer Detail Component

– Implement CustomerDetailComponent class file customer-detail.component.ts :

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

import { switchMap } from 'rxjs/operators';
import { Router, ActivatedRoute, ParamMap } from '@angular/router';

import { Location } from '@angular/common';

import { Observable } from 'rxjs';

import { Customer } from '../customer';
import { CustomerService } from '../customer.service';

@Component({
  selector: 'app-customer-detail',
  templateUrl: './customer-detail.component.html',
  styleUrls: ['./customer-detail.component.css']
})
export class CustomerDetailComponent implements OnInit {

  customer$: Observable;

  constructor(  
    private route: ActivatedRoute,
    private location: Location,
    private service: CustomerService
  ) { }

  ngOnInit() {
    this.customer$ = this.route.paramMap.pipe(
      switchMap((params: ParamMap) =>
        this.service.getCustomer(params.get('id')))
    );
  }

  goBack(): void {
    this.location.back();
  }
}

Location is an Angular service for interacting with the browser. Depending on LocationStrategy, Location will either persist to the URL’s path or the URL’s hash segment.
ActivatedRoute contains the information about a route that can be used to traverse and retrieve the state of router tree.

We implement ngOnInit() to get info of a customer by service.getCustomer(params['id'])).
Using Location, a goBack() function navigates backward one step in the browser’s history stack.

– Implement CustomerDetailComponent template file customer-detail.component.html :

{{customer.firstname}}

  • Id: {{customer.id}}
  • Firstname: {{customer.firstname}}
  • Lastname: {{customer.lastname}}
  • Age: {{customer.age}}
  • Nationality: {{customer.nationality}}
PageNotFound Component

Implement PageNotFoundComponent template file page-not-found.component.html :

404 Error!

PAGE NOT FOUND

Source Code

How to run the below sourcecode:

1. Download Angular-6-Routing-Navigation.zip file -> Then extract it to Angular-6-Routing-Navigation folder.
2. Go to Angular-6-Routing-Navigation folder
3. Run the app by commandline: ng serve --open

-> Sourcecode:

Angular-6-Routing-Navigation



By grokonez | June 23, 2018.

Last updated on May 17, 2019.



Related Posts


4 thoughts on “Angular 6 Routing/Navigation – with Angular Router Service”

  1. this.customers$ = this.service.getCustomersByNationality(‘US’);

    error showing on all folders:
    customer-us, customer-uk and customer-details folders show same errors.

    1. Hi israrel belete
      replace the the customer.service.ts file to this code after the customer data are defined

      @Injectable({
        providedIn: 'root'
      })
      
      @Injectable()
      export class CustomerService {
        getCustomers() { return of(CUSTOMERS); }
      
        getCustomer(id: number | string) {
          return this.getCustomers().pipe(
            // (+) before `id` turns the string into a number
            map(customers => customers.find(customer => customer.id === +id))
          );
        }
      
        getCustomersByNationality(nationality: string){
          return this.getCustomers().pipe(
            map(customers => customers.filter(cust => cust.nationality === nationality))
          )
        }
      }
      

Got Something To Say:

Your email address will not be published. Required fields are marked *

*