Passing Data between Routed Components in Angular

In Angular, navigating between routed components often requires passing data from one component to another. This can be achieved through various methods, each with its own advantages and use cases. In this tutorial, we will explore the different approaches to pass data between routed components in Angular.

Using Route Parameters

One common way to pass data between components is by using route parameters. You can define a path in your routing configuration with a parameter, like /:id, and then navigate to that route while passing the ID as a parameter.

// routes.ts
const routes: Routes = [
  { path: 'detailView/:id', component: DetailedViewComponent }
];

To navigate to this route and pass an ID, you can use the routerLink directive or the navigateByUrl method of the Router service.

// navigation.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-navigation',
  template: `
    <a [routerLink]="['/detailView', list.id]">View</a>
  `
})
export class NavigationComponent {
  constructor(private router: Router) {}
}

In the component that receives the route parameter, you can inject the ActivatedRoute service and subscribe to its params observable to get the ID.

// detailed-view.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-detailed-view',
  template: `
    <p>Detail view for ID: {{ id }}</p>
  `
})
export class DetailedViewComponent implements OnInit {
  id: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    this.route.params.subscribe(params => {
      this.id = params['id'];
    });
  }
}

Using a Shared Service

Another approach to pass data between components is by using a shared service. You can create a service that stores the data and inject it into both components.

// data.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: any;

  setData(data: any): void {
    this.data = data;
  }

  getData(): any {
    return this.data;
  }
}

In the component that sets the data, you can inject the DataService and call its setData method.

// first.component.ts
import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-first',
  template: `
    <button (click)="routeWithData()">Route with data</button>
  `
})
export class FirstComponent {
  constructor(private dataService: DataService, private router: Router) {}

  routeWithData(): void {
    this.dataService.setData({ someData: 'some value' });
    this.router.navigate(['/second']);
  }
}

In the component that receives the data, you can inject the DataService and call its getData method.

// second.component.ts
import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-second',
  template: `
    <p>Received data: {{ data }}</p>
  `
})
export class SecondComponent {
  data: any;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.data = this.dataService.getData();
  }
}

Using the Router’s State

In Angular 7.2 and later, you can pass data between components using the router’s state.

// first.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-first',
  template: `
    <button (click)="routeWithData()">Route with data</button>
  `
})
export class FirstComponent {
  constructor(private router: Router) {}

  routeWithData(): void {
    this.router.navigateByUrl('/second', { state: { someData: 'some value' } });
  }
}

In the component that receives the data, you can access the router’s state using the getCurrentNavigation method.

// second.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-second',
  template: `
    <p>Received data: {{ data }}</p>
  `
})
export class SecondComponent {
  data: any;

  constructor(private router: Router) {}

  ngOnInit(): void {
    this.data = this.router.getCurrentNavigation().extras.state;
  }
}

Conclusion

In conclusion, there are several ways to pass data between routed components in Angular. You can use route parameters, a shared service, or the router’s state. Each approach has its own advantages and use cases. By choosing the right method for your application, you can efficiently pass data between components and create a seamless user experience.

Leave a Reply

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