DEV Community

Harlin Seritt
Harlin Seritt

Posted on

Angular: Sending data from one component to another

There are several ways to share data between Angular components, each with its own advantages and disadvantages.

One way to share data is to use a shared service. With this approach, a singleton service is created that holds the data and methods to set and get the data.

This is a suitable method when the data needs to be shared between multiple unrelated components.

The service can also be used to share data between different parts of the application.

Another way to share data is to use the Input and Output decorators.

This approach is suitable when the parent-child relationship exists between the components and data needs to be passed from parent to child or vice versa.

It's a simple way to share data, but it can be less flexible than using a shared service, since it's only meant to share data between parent and child components.

Another way to share data is to use a Subject or BehaviorSubject from the rxjs library. This approach allows components to share data using the observer pattern.

This is a more advanced technique, and it's suitable when you need to share data between multiple components and perform some operations on the data before it's shared.

@Input / @Output

As mentioned, you can use the @Input() decorator to pass data from a parent component to a child component, and the @Output() decorator along with EventEmitter to pass data from a child component to a parent component.

For example, in the parent component's template, you can bind a property to the child component's input:

<app-child [inputData]="data"></app-child>
Enter fullscreen mode Exit fullscreen mode

And in the child component's class, you can use the @Input() decorator to receive the data:

export class ChildComponent {
  @Input() inputData: any;
}
Enter fullscreen mode Exit fullscreen mode

To pass data from a child component to a parent component, you can use the @Output() decorator along with EventEmitter in the child component:

export class ChildComponent {
  @Output() dataEvent = new EventEmitter<any>();

  sendData() {
    this.dataEvent.emit(this.data);
  }
}
Enter fullscreen mode Exit fullscreen mode

And in the parent component's template, you can listen for the event and handle the data:

<app-child (dataEvent)="handleData($event)"></app-child>
Enter fullscreen mode Exit fullscreen mode
export class ParentComponent {
  handleData(data: any) {
    // do something with the data
  }
}
Enter fullscreen mode Exit fullscreen mode

Shared Service

You can use a shared service to pass data between components that are not directly related. Here's an example of how you can do this:

Create a new service by running the following command in your terminal: ng generate service shared

In the shared.service.ts file, you can create a new property to hold the data and methods to set and get the data.

export class SharedService {
  private data: any;

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

  getData() {
    return this.data;
  }
}
Enter fullscreen mode Exit fullscreen mode

In the component where you want to set the data, you can inject the SharedService and call the setData() method to set the data.

export class ComponentA {
  constructor(private sharedService: SharedService) {}

  setData() {
    this.sharedService.setData(this.data);
  }
}
Enter fullscreen mode Exit fullscreen mode

In the component where you want to get the data, you can inject the SharedService and call the getData() method to get the data.

export class ComponentB {
  data: any;

  constructor(private sharedService: SharedService) {
    this.data = this.sharedService.getData();
  }
}
Enter fullscreen mode Exit fullscreen mode

In your app.module.ts file, you need to import and provide the service.

import { SharedService } from './shared.service';

@NgModule({
  ...
  providers: [SharedService],
  ...
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

This way, both ComponentA and ComponentB have access to the same instance of the SharedService, and can share data by setting and getting it through the service's methods.

BehaviorSubject from RXJS

You can also use a Subject or a BehaviorSubject from rxjs library to share data between component with a observer pattern.

Here's an example:

In the shared service, import the BehaviorSubject from the rxjs library and create a new instance of it.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class SharedService {
  private data = new BehaviorSubject<any>(null);
  currentData = this.data.asObservable();

  constructor() { }

  updateData(data: any) {
    this.data.next(data);
  }
}
Enter fullscreen mode Exit fullscreen mode

In the component where you want to set the data, you can inject the SharedService and call the updateData() method to set the data.

import { Component } from '@angular/core';
import { SharedService } from './shared.service';

@Component({
  selector: 'app-component-a',
  template: `
    <button (click)="setData()">set data</button>
  `
})
export class ComponentA {
  data = { message: 'Hello' };

  constructor(private sharedService: SharedService) { }

  setData() {
    this.sharedService.updateData(this.data);
  }
}
Enter fullscreen mode Exit fullscreen mode

In the component where you want to get the data, you can inject the SharedService and subscribe to the currentData observable to get the data.

import { Component } from '@angular/core';
import { SharedService } from './shared.service';

@Component({
  selector: 'app-component-b',
  template: `
    <p>{{ data?.message }}</p>
  `
})
export class ComponentB {
  data: any;

  constructor(private sharedService: SharedService) {
    this.sharedService.currentData.subscribe(data => {
      this.data = data;
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Summary

The best method for sharing data between Angular components depends on the specific requirements of your application.

Shared services are a good choice for sharing data between multiple, unrelated components, while Input and Output decorators are good for sharing data between parent and child components, and Subject or BehaviorSubject can be used when you need to share data with observer pattern.

Top comments (0)

Dark Mode

🌚 Friends don't let friends browse without dark mode.

Just kidding, it's a personal preference. But you can change your theme, font, etc. in your settings.