How To Pass Parameters To The Route In Angular.

How To Pass Parameters To The Route In Angular.

In this article, We will learn how to pass parameters (route parameters) or data to the Route in Angular. Let's start by looking at how to create a route that accepts the parameter. The routerLink directive is then used to pass the arguments to the route. Finally, we'll look at how to use the ActivatedRoute Service to get the parameters. Either the snapshot method or the subscribe method can be used to retrieve the parameters. We'll look at both of these approaches.

There are numerous instances in which parameters must be passed to the route. To navigate to the product detail view, for example, we must supply the product ID to the component so that it may retrieve and display it to the user.

Let's expand on the Routing & Navigation article's application by adding a product detail page that displays product details based on the Product ID given in the URL. This article's code may be found on Github under the folder parameters.

What are Route Parameters

The Route parameters are an important aspect of determining the route because they are dynamic.

Take, for example, the following path.

{ path: 'product', component: ProductComponent }

Only if the URL is /product will the above route work.

Our URL for retrieving product information should look like this:

/product/1
/product/2

The id of the product is the second URL segment (1 and 2). The id is dynamic and changes depending on the Product selected. To deal with such a situation, the angular router allows us to use route parameters, which allow us to deliver any dynamic value for a URL segment.

How to Pass parameters to Angular Route

Defining the Route

As illustrated below, we can define a parameter by adding a forward slash, a colon, and a placeholder (id).

{ path: 'product/:id', component: ProductDetailComponent }

Now the aforementioned path corresponds to the URLs /product/1, /product/2, and so on.

If you have more than one argument, you can add another forward slash followed by a colon and a placeholder to make it longer.

{ path: 'product/:id/:id1/:id2', component: ProductDetailComponent }

Parameters with the names id, id1 & id2 are placeholders. They'll come in handy for fetching parameter values.

Defining the Navigation

We must now specify both the path and the routerLink directive's route parameter.

As illustrated below, the productID is added as the second entry to the routerLink parameters array.

<a [routerLink]="['/Product', ‘2’]">{{product.name}} </a>

This corresponds to the URL /product/2.

OR

<a [routerLink]="['/Product', product.productID]">{{product.name}} </a>

This takes the value of id from the product object dynamically.

Retrieve the parameter in the component

Finally, our component must extract the URL's route parameter.

To access the parameter value, use the ActivatedRoute service from the angular/router module.

ActviatedRoute

The ActivatedRoute is a service that keeps track of the loaded Component's presently activated route.

We must import ActivatedRoute into our component in order to use it.

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

Then use dependency injection to inject it into the component.

constructor(private _Activatedroute:ActivatedRoute)

ParamMap

Angular stores all route parameters in the parameterMap object, which can be retrieved through the ActivatedRoute service.

The ParamMap makes working with parameters a lot easier. The value of the parameters in the component can be retrieved using the get or getAll methods. To check if a parameter exists, use the has method.

The ActivatedRoute may be used in two ways to get the parameter value from the ParamMap object.
  1. Using Snapshot
  2. Using observable

Using Snapshot

this.id=this._Activatedroute.snapshot.paramMap.get("id");

The snapshot property returns the route's original value. As illustrated above, you can then use the paramsMap array to get the value of the id.

Using Observable

this._Activatedroute.paramMap.subscribe(params => { 
    this.id = params.get('id'); 
});

You may get the value of id by subscribing to the activateRoute's paramMap observable property, as seen above.

Why use observable

When the component is initialized, we normally obtain the value of the parameter in the ngOnInit life cycle hook.

When the user returns to the component, Angular reuses the existing instance rather than creating a new one. The component's ngOnInit function is not called again in this situation. As a result, you'll need a mechanism to access the parameter's value.

You may get the most recent value of the parameter and update the component by subscribing to the observable paramMap property.

Passing Parameters to Route: Example

The whole code list can be seen here.

Add the following code under the product.component.ts file:

import { Component, OnInit } from '@angular/core';
 
import { ProductService } from './product.service';
import { Product } from './product';
 
@Component({
  templateUrl: './product.component.html',
})
 
export class ProductComponent
{
 
   products:Product[];
   
   constructor(private productService:ProductService){
   }
 
   ngOnInit() {
     this.products=this.productService.getProducts();
   }
  
}

Add the following code under the product.component.html file:

<h1>Product List</h1>
<div class='table-responsive'>
    <table class='table'>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let product of products;">
                <td>{{product.productID}}</td>
                <td><a [routerLink]="['/product',product.productID]">{{product.name}} </a> </td>
                <td>{{product.price}}</td>
            </tr>
        </tbody>
    </table>
</div>

Add the following code under the product.service.ts file:

import { Observable } from 'rxjs';
import {Product} from './Product'
 
 
export class ProductService{
 
    public getProducts() {
 
        let products:Product[];
 
        products=[
            new Product(1,'Memory Card',500),
            new Product(2,'Pen Drive',750),
            new Product(3,'Power Bank',100)
        ]
 
        return products;               
    }
 
 
    public getProduct(id) {
        let products:Product[]=this.getProducts();
        return products.find(p => p.productID==id);
    }
 
 
}

Add the following code under the product.ts file:

export class Product { 
 
    constructor(productID:number,    name: string ,   price:number) {
        this.productID=productID;
        this.name=name;
        this.price=price;
    }
 
    productID:number ;
    name: string ;
    price:number;
 
}

We inserted product.productID as the second argument to the routerLink parameters array in product.component.html.

<a [routerLink]="['/product',product.productID]">{{product.name}} </a> 

Product Details Component

Now, Open the product-detail.component.ts  and put the following code:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router,ActivatedRoute } from '@angular/router';
 
import { ProductService } from './product.service';
import { Product } from './product';
 
 
@Component({
  templateUrl: './product-detail.component.html',
})
 
export class ProductDetailComponent
{
 
   product:Product;
   id;
   
   constructor(private _Activatedroute:ActivatedRoute,
               private _router:Router,
               private _productService:ProductService){
   }
 
  
   /* Using snapshot */
   // ngOnInit() {
 
   //    //This still works but is deprecated
   //    //this.id=this._Activatedroute.snapshot.params['id'];  
 
   //    this.id=this._Activatedroute.snapshot.paramMap.get("id");
 
      
   //    let products=this._productService.getProducts();
   //    this.product=products.find(p => p.productID==this.id);
   // }
   
 
   /* Using Subscribe */
   
   sub;
 
   ngOnInit() {
 
      this.sub=this._Activatedroute.paramMap.subscribe(params => { 
         console.log(params);
          this.id = params.get('id'); 
          let products=this._productService.getProducts();
          this.product=products.find(p => p.productID==this.id);    
      });
 
      // This params is deprecated
 
      //this.sub=this._Activatedroute.params.subscribe(params => { 
      //    this.id = params['id']; 
      //    let products=this._productService.getProducts();
      //    this.product=products.find(p => p.productID==this.id);    
      //
      //});
   }
 
   ngOnDestroy() {
     this.sub.unsubscribe();
   }
   
   onBack(): void {
      this._router.navigate(['product']);
   }
}

Add the following code under the product-detail.component.html file:

<h3>Product Details Page</h3>
 
 
product : {{product.name}}
price : {{ product.price}}
<p>
    <a class='btn btn-default' (click)="onBack()">Back </a>
</p>

We imported the router and ActivatedRoute from the angular router module into the ProductDetailComponent.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router,ActivatedRoute } from '@angular/router';

We inject the ActivatedRoute, Router, and ProductService services into the constructor.

constructor(private _Activatedroute:ActivatedRoute,
            private _router:Router,
            private _productService:ProductService){
}

Finally, we use the ngOnInit life cycle hook to get the value of the id argument, which we then use to get the product's data.

It's worth noting that there are two methods for retrieving data.

Using snapshot

ngOnInit() {

    //This still works but is deprecated
    //this.id=this._Activatedroute.snapshot.params['id'];  

    this.id=this._Activatedroute.snapshot.paramMap.get("id");

     
    let products=this._productService.getProducts();
    this.product=products.find(p => p.productID==this.id);
}

Using Subscribe

In ProductDetailcomponet.ts, we used the snapshot method to obtain the parameter. Remove the ngOnInit and replace it with the following code to subscribe to params.

We recommend that you use the subscribe technique because it allows you to dynamically respond to parameter changes.

ngOnInit() {

   this.sub=this._Activatedroute.paramMap.subscribe(params => { 
      console.log(params);
       this.id = params.get('id'); 
       let products=this._productService.getProducts();
       this.product=products.find(p => p.productID==this.id);    
   });

   // This params is deprecated

   //this.sub=this._Activatedroute.params.subscribe(params => { 
   //    this.id = params['id']; 
   //    let products=this._productService.getProducts();
   //    this.product=products.find(p => p.productID==this.id);    
   //
   //});
}

Add following code is the complete code of the app.routing.ts file:

import { Routes } from '@angular/router';
 
import { HomeComponent} from './home.component'
import { ContactComponent} from './contact.component'
import { ProductComponent} from './product.component'
import { ErrorComponent} from './error.component'
 
import { ProductDetailComponent} from './product-detail.component'
 
export const appRoutes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'contact', component: ContactComponent },
  { path: 'product', component: ProductComponent },
  { path: 'product/:id', component: ProductDetailComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', component: ErrorComponent }
];

The following route has been added to our routes array.

{ path: 'product/:id', component: ProductDetailComponent },

Update the app.component.ts file with following code:

import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Routing Module - Parameters Demo';
}

Add the following code under the  app.component.html file:

<div class="container">
 
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" [routerLink]="['/']"><strong> {{title}} </strong></a>
    </div>
    <ul class="nav navbar-nav">
        <li><a [routerLink]="['home']">Home</a></li>
        <li><a [routerLink]="['product']">Product</a></li>
        <li><a [routerLink]="['contact']">Contact us</a></li>
    </ul>
  </div>
</nav>
 
 <router-outlet></router-outlet>
 
</div>

Now, put the following code under the contact.component.ts:

import {Component} from '@angular/core';
 
@Component({
     template: `<h1>Contact Us</h1>
                <p>TekarticlesHub </p>
                `
})
export class ContactComponent {
}

Add the following code under the home.component.ts file:

import {Component} from '@angular/core';
 
@Component({
    template: `<h1>Welcome!</h1>
              <p>This is Home Component </p>
             `
})
 
export class HomeComponent {
}

Update the error.component.ts file with the following code:

import {Component} from '@angular/core';
 
@Component({
    template: `<h1>Page not found</h1>
               <p>This is a Error Page</p>
              `
})
 
export class ErrorComponent {
}

Update the app.module.ts file using the following code:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
 
import { RouterModule } from '@angular/router';
 
import { AppComponent } from './app.component';
import { HomeComponent} from './home.component'
import { ContactComponent} from './contact.component'
import { ProductComponent} from './product.component'
import { ErrorComponent} from './error.component'
import { ProductDetailComponent} from './product-detail.component'
 
import { ProductService } from './product.service';
 
import { appRoutes } from './app.routes';
 
@NgModule({
  declarations: [
    AppComponent,HomeComponent,ContactComponent,ProductComponent,ErrorComponent,ProductDetailComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot(appRoutes)
  ],
  providers: [ProductService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Example Of Angular Route Parameters


ActivatedRoute

The ActivatedRoute service contains a wealth of information, such as:

url: This field produces an array of Url Segment objects, each describing a single URL segment that matched the current route.

params: This property produces a parms object that contains a list of URL parameters that are indexed by name.

queryParams: This property returns a parms object that is indexed by name and describes the URL query parameters.

fragment: The URL fragment is returned as a string by this attribute.

Snapshot: This is a first look at the route.

data: The data object provided for the route is stored in an Observable.

Component: This is the route's component. It's a recurring theme.

outlet: The RouterOutlet that was used to render the route's name. The outlet name is primary for an unnamed outlet.

routeConfig: This is the route configuration for the route with the origin path.

parent: When employing child routes, an ActivatedRoute that contains information from the parent route is created.

firstChild: The first ActivatedRoute in the list of child routes is found here.

children: contains all of the active child routes under the current route

pathFromRoot: The path from the router state tree's root to this route

Conclusion

We lerned how to send data or parameters to the Route. The parameters are supplied to the route via the routerLink directive's routerLink parameters. By reading the params collection of the snapshot object or subscribing to the params observable, we can get the parameters from the ActivatedRoute Service.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in the comment section.

Post a Comment

Previous Post Next Post