Tuesday, January 7, 2020

Angular 9 Router Tutorial – Configure Routing & Navigation

Install Angular 9 Project
Run command to install Angular project for Angular Router demo.
ng new angular-routing-tutorial
Angular CLI will add app-routing.module.ts file in Angular project. In this file we will define all the routing configuration.
cd angular-routing-tutorial
Install Bootstrap, we will use Bootstrap 4 UI components for the demo purpose.
npm install bootstrap
Place bootstrap.min.css file path in the styles array in package.json:
"styles": [
      "node_modules/bootstrap/dist/css/bootstrap.min.css",
      "src/styles.css"
]
Check Angular 9 routing app by entering http://localhost:4200 url in the browsers address bar.
ng serve --open
Configure Routes & RouterModule
Before we configure routes in Angular, we have to have a look on the app’s navigation architecture and install the components based on the diagram.

Angular 9 Router Tutorial – Configure Routing & Navigation

Angular 9 Routing Example
As per the app, architecture create the components by using the Angular CLI command in the terminal.
ng generate component home
ng generate component about
ng generate component contact
ng generate component products
ng generate component product-detail
ng generate component product-detail
ng generate component NoPageFound
In AppRoutingModule Routes and RouterModule service are responsible for enabling routing service in Angular.
import {Routes, RouterModule} from "@angular/router";
Head over to app-routing.module.ts and import the components for which routing has to be configured.
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ProductsComponent } from './products/products.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { ContactComponent } from './contact/contact.component';
import { NoPageFoundComponent } from './no-page-found/no-page-found.component';
Here, define the path of the route using the Angular components. Here in the path: "..." insert your route name.
const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'products', component: ProductsComponent },
  { path: 'product-detail/:id', component: ProductDetailComponent },
  { path: 'contact', component: ContactComponent },
  { path: '**', component: NoPageFoundComponent }
];
Here are the routes we just created in Angular 8/9.

Angular 9 Route Matching Strategies

Angular offers prefix and full route matching strategies. These are built-in route matching mechanism to identify if the existing browser’s URL is prefixed with the path.
pathMatch: 'full' signifies that the complete URL path requires to be matched and is utilized by the route matching mechanism.
In the below example, we are redirecting to the /home component and matching the empty path using the pathMatch: ‘full’ property.
{ path: '', redirectTo: '/home', pathMatch: 'full' }
The redirectTo property helps you redirect to the specified path if the particular route is matched.
pathMatch: 'prefix' indicates, If the route matching strategy of a particular route is set to prefix, In this case, the router identifies if the starting URL in the browser is prefixed with the route’s path, and it gets the associated component.
Here we are checking if the current URL in the browser prefixed with the path.
{ path:  'about', pathMatch: 'prefix', component:  AboutComponent}
Wildcard Route in Angular 8/9
If the user lands on the page, which doesn’t exist in the app, to get rid of this problem, we can redirect the user to the 404 page. Fortunately, to sort out this issue, we have a wildcard route in Angular. It can be done quickly bypassing double asterisk, and it can be written something like this path: "**" here is how you set wildcard route in routes array, check out the example below.
const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'products', component: ProductsComponent },
  { path: 'product-detail/:id', component: ProductDetailComponent },
  { path: 'contact', component: ContactComponent },
  { path: '**', component: NoPageFoundComponent }
];
Setting up wildcard route in Angular is simple, you have to create a component first and let’s call it NoPageFoundComponent or whatever you and then import in the app-routing.module.ts file:
Go to no-page-found.component.html and add the following HTML code in it and then enter some random wrong name in the browser’s address bar.
<div class="col-md-12">
    <div class="error-template">
        <h3>Oops!</h3>
        <h2>404 Not Found</h2>
        <div class="error-details mb-3">
            Sorry, Requested page not found!
        </div>
        <div class="error-actions">
            <a routerLink="/home" class="btn btn-danger btn-lg">
                Go Back to Home
            </a>
        </div>
    </div>
</div>
Angular 9 Wildcard Route
Angular 9 Route Parameters
Next, we will learn how to add a router for products and product-details components with the help of Angular 8|9 route parameters or params. Here we will create a product-details route with id parameter. There are many ways to locate parameters in Angular 9 Router.

Here is the quick look of the code we added in the app-routing.module.ts.
import { ProductsComponent } from './products/products.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
const routes: Routes = [
  { path: 'products', component: ProductsComponent },
  { path: 'product-detail/:id', component: ProductDetailComponent }
];
Next, go to products.component.ts file and add the products array.
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
  Products = [
    {
      id: "ABC8441189035",
      name: "Tshirt",
      description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
    },
    {
      id: "DEF6510463347",
      name: "Shoes",
      description: "Proin ac metus in diam porttitor viverra eu sit amet ligula."
    },
    {
      id: "GHI0831819467",
      name: "Handbags",
      description: "Duis sodales dui vitae urna varius, at ullamcorper purus tempor."
    }
  ]
  constructor() { }
  ngOnInit() { }
}
Now, let’s understand what does the below code mean. We are passing the id parameter in the [routerLink]="..." route and sending the data to the params. When the user clicks on the product then the user will be redirected to associated id product in the product-details page.

<a [routerLink]="['/product-detail/', products.id]" class="btn btn-danger">Check Product</a>
Next, go to products.component.html file and add the following code.
<div class="row">
    <div class="col-sm-4" *ngFor="let products of Products">
        <div class="card mb-3">
            <div class="card-body">
                <h5 class="card-title">{{products.name}}</h5>
                <p class="card-text">{{products.description}}</p>
                <a [routerLink]="['/product-detail/', products.id]" class="btn btn-danger">Check Product</a>
            </div>
        </div>
    </div>
</div>
GET Angular 9 Route Parameter with ActivatedRoute
We learned in the previous how to send parameters in the Angular 9 router and create dynamic routes. Now, we will use the Activated route API to get the route parameter in an Angular 9 app.
Go to product-detail.component.ts and add the below code in it.
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
  selector: 'app-product-detail',
  templateUrl: './product-detail.component.html',
  styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent {
  product_id: string;
  constructor(private actRoute: ActivatedRoute) {
    this.product_id = this.actRoute.snapshot.params.id;
  }
}
Here we imported the ActivatedRoute service and set the product_id variable. Then injected the ActivatedRoute service in the constructor and used the snapshot.params.id with the help of ActivatedRoute and assign the id parameter to the product_id variable.

Next, go to product-detail.component.html file and add the below code, this will show the associated product id when the user visit the product-details page.
<h5 class="card-title">Product Id is: {{product_id}}</h5>
Angular 9 Router Outlet & Navigation Directives
The Router-Outlet directive allows components to display data dynamically based on the existing browser’s URL or path. It can be added inside the app.component.ts file, and multiple router outlets can be placed in an Angular 9 app for fulfilling the advanced routing cases. We are using the Bootstrap container class and wrapping the router-outlet in it.
<div class="container text-center">
  <router-outlet></router-outlet>
</div>
Configure Routes with Navigation Directives
To configure the routers in Angular and active class, we have routerLink and routerLinkActive directives, check out below how we used both the navigation directives in app.component.ts file.
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-5">
  <div class="container">
    <a class="navbar-brand" href="#">Angular 9 Routing Tutorial</a>
    <ul class="nav nav-pills">
      <li class="nav-item">
        <a class="nav-link" routerLinkActive="active" routerLink="/home">Home</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLinkActive="active" routerLink="/about">About</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLinkActive="active" routerLink="/products">Products</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLinkActive="active" routerLink="/contact">Contact</a>
      </li>
    </ul>
  </div>
</nav>
<div class="container text-center">
  <router-outlet></router-outlet>
</div>