Pass data to Route in Angular

By Arvind Rai, March 13, 2024
On this page we will learn to pass data to navigation in our Angular routing application. We can pass data to navigation by two ways.
1. By configuring data in route configuration.
2. By passing state to RouterLink, Router.navigate() and Router.navigateByUrl().
To fetch value from data, use ActivatedRoute.data. To fetch value from state, use Router.lastSuccessfulNavigation and access extras from it. Using extras, we can get state object passed to navigation.

1. Route: data

Route contains properties to define a single route. An array of Route objects creates the Routes object. We can pass static data to navigation using data property of Route.
interface Route {
  data?: Data
  ------
} 
Route.data gives the object of Data that represents static data associated with a particular route.
data: {
    [key: string | symbol]: any;
}; 
Find the code snippet of route configuration passing data.
const routes: Routes = [
	{
		path: 'countrydetail',
		component: CountryDetailComponent,
		data: {isdCode: 91, countryName: 'India'}
	}
] 

2. Fetch 'data' from Route Configurations

We can fetch data from route configurations by subscribing ActivatedRoute.data. The ActivatedRoute contains the information about a route associated with a component that is loaded in an outlet.
ActivatedRoute declares data property as below.
class ActivatedRoute {
   data: Observable<Data>
   ------
} 
Now let us see how to use ActivatedRoute.data to fetch data defined in route configurations.
Suppose I have following route.
const routes: Routes = [
    {
        path: 'productDetail',
        component: ProductDetailComponent,
        data: { compId: 11, compName: 'PQR' }
    }
] 
By subscribing ActivatedRoute.data, we access route data values as below.
@Component({
    template: ''
})
export class ProductDetailComponent implements OnInit {
  constructor(private route: ActivatedRoute) { }
  ngOnInit() {
    this.route.data.subscribe((data: Data) => {
      console.log(data['compId']); // Output - 11
      console.log(data['compName']); // Output - PQR
    });
  } 
} 


3. NavigationBehaviorOptions: state

NavigationBehaviorOptions provides options to modify the router navigation strategy. We can pass our data to navigation using its state property of NavigationBehaviorOptions declared as below.
interface NavigationBehaviorOptions {
  state?: {...}
  ------
} 
NavigationExtras is child interface of NavigationBehaviorOptions. We can pass state object to following methods and directive.
a. RouterLink
b. Router.navigate()
c. Router.navigateByUrl()
state object is created using following semantics.
state?: {
    [k: string]: any;
} 
For example: {countryId: 111, countryName: ‘India’} .
Using state object, we can pass both static and dynamic data. RouterLink directive has input property as state. We can pass user object using this state as bellow.
<a routerLink="/company" [state]="{compId: 101, compName: 'ABCD'}">link</a> 
Passing dynamic state : To pass state object dynamically, create a component property and pass it to routerLink using property binding.
TS code:
stateObj = {compId: 101, compName: 'ABCD'}; 
HTML code:
<a routerLink="/company" [state]="stateObj">link</a> 
Fetch value of ‘state’ : Suppose I have a route configuration for the path /company that will visit CompanyComponent .
          
const routes: Routes = [
	{
		path: 'company',
		component: CompanyComponent,
	}
] 
To fetch ‘state’ value, use Router class in CompanyComponent as below.
@Component({
    template: ''
})
export class CompanyComponent implements OnInit {
    constructor(private router: Router) { }
    ngOnInit() {
       const stateObj = this.router.lastSuccessfulNavigation?.extras.state;
       console.log(stateObj); 
    }
} 
To pass ‘state’ using Router.navigate(), create NavigationExtras object initializing ‘state’ property. NavigationExtras implements NavigationBehaviorOptions interface.
Now pass NavigationExtras object as second argument of navigate() method.
this.router.navigate(['company'],
	{
		state: { compId: 101, compName: 'ABCD' }
	}); 
We can also dynamically assign ‘state’ values.
navigateToCompany() {
	const cmpId = 11;
	const cmpName = 'ABCD';
	this.router.navigate(['company'],
		{
			state: { compId: cmpId, compName: cmpName }
		});
} 
Access ‘state’ value using Router as below.
const stateObj = this.router.lastSuccessfulNavigation?.extras.state; 
We can pass ‘state’ to Router.navigateByUrl using NavigationBehaviorOptions. Create the NavigationBehaviorOptions object initializing its ‘state’ property and pass this object as second parameter of Router.navigateByUrl() function.
customerDetail() {
	const cid = 110;
	const cname = 'PQRS';
	this.router.navigateByUrl('/customerDetail',
		{
			state: { custId: cid, custName: cname }
		});
} 
Access ‘state’ value using Router as below.
const stateObj = this.router.lastSuccessfulNavigation?.extras.state; 


7. Complete Example

app.routes.ts
import { Routes } from '@angular/router';
import { ProductComponent } from './product.component';
import { CustomerComponent } from './customer.component';

export const ROUTES: Routes = [
    {
        path: 'customer',
        component: CustomerComponent,
        data: { custId: 101, custName: 'EFGH', city: 'Varanasi' }
    },
    {
        path: 'product',
        component: ProductComponent
    }
]; 
app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { ROUTES } from './app.routes';

export const APP_CONFIG: ApplicationConfig = {
  providers: [
    provideRouter(ROUTES)
  ]
}; 
app.component.ts
import { Component } from '@angular/core';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterModule],
  template: `
   <nav>
   <ul>
       <li>
         <a routerLink="/customer">Customer Details</a>
       </li>
       <li>
         <a routerLink="/product" [state]="stateObj">Product Details</a>
       </li>
   </ul>
   </nav>
   <button (click)="goToProduct1()">Pruduct 1</button>
   <button (click)="goToProduct2()">Pruduct 2</button>
   <br/>
   <router-outlet></router-outlet> 
   `
})
export class AppComponent {
  stateObj = { pid: 21, pname: 'PQRS', category: 'Games' };
  constructor(private router: Router, private route: ActivatedRoute) { }
  goToProduct1() {
    this.router.navigate(['/product'], {
      state: this.stateObj,
      relativeTo: this.route
    });
  }
  goToProduct2() {
    this.router.navigateByUrl('/product', {
      state: this.stateObj
    });
  }
} 
customer.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ActivatedRoute, Data, Router } from '@angular/router';

@Component({
   standalone: true,
   imports: [CommonModule],
   template: 'Customer Component'
})
export class CustomerComponent implements OnInit {
   constructor(private route: ActivatedRoute) { }
   ngOnInit(): void {
      this.route.data.subscribe((data: Data) => {
         const custId = data['custId'];
         console.log(custId);

         const custName = data['custName'];
         console.log(custName);

         const city = data['city'];
         console.log(city);
      });
   }
} 
product.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router } from '@angular/router';

@Component({
   standalone: true,
   imports: [CommonModule],
   template: 'Product Component'
})
export class ProductComponent implements OnInit {
   constructor(private router: Router) { }
   ngOnInit() {
      const stateObj = this.router.lastSuccessfulNavigation?.extras.state;
      console.log(stateObj?.['pid']);
      console.log(stateObj?.['pname']);
      console.log(stateObj?.['category']);
   }
} 

8. References

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE












©2024 concretepage.com | Privacy Policy | Contact Us