Methods to Share Data Between Angular Components

Methods to Share Data Between Angular Components

03 Jul 2024
Advanced
222K Views
16 min read
Learn with an interactive course and practical hands-on labs

Self-Paced Angular Certification Course

Sharing Data Between Angular Components: An Overview

Sharing data between Angular Components is a real challenge for Angular developers. Angular provides several methods to accomplish this task effectively and efficiently. In this Angular tutorial, we'll dive into the four data-sharing methods between Angular Components. Let's get started with these easy ways to connect your Angular components!

Read More:-  Top 50+ Angular Interview Questions & Answers

What is Data Sharing between Angular Components?

Data sharing between components in Angular refers to exchanging data between them. This is important when developing interactive and dynamic applications, as components are usually required to communicate and exchange data to perform their functions.

Methods to Share Data Between Angular Components

There are four Methods to Share Data between Angular Components:

  1. Parent-to-Child: Sharing Data via @Input
  2. Child-to-Parent: Sharing Data via @Output() and EventEmitter
  3. Unrelated Components: Sharing Data via a Service
  4. Child-to-Parent: Sharing Data via ViewChild

Want to learn Angular on your schedule or with live guidance? We've got you covered! Choose between our self-paced or live Angular Certification Course. Enroll today!

Certification NameTraining ModeCost / Batch 
Self-Paced Angular Certification CourseSelf Paced₹749 (57.12 % OFF)
Angular Certification TrainingLive Training16 June (Sat , Sun)

1. Parent-to-Child: Sharing Data via @Input

Input properties allow to passing of data from a parent component to its child component. By defining a property in the child component with the @Input() decorator, you can receive the data from the parent component.

Parent-to-Child: Sharing Data via @Input

Example of Parent-to-Child: Sharing Data via @Input

parent.component.ts


import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent{
  parentMessage = "Hello message from parent!"
  constructor() { }
}
        

child.component.ts


import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
      Say {{ message }}
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  @Input() childMessage: string;

  constructor() { }

}
Here we will get “Hello message from parent!” message from the parent component into the child component inside the childMessage variable.

2. Child-to-Parent: Sharing Data via @Output() and EventEmitter

If you want to pass data from the child component to the parent component use @Output() and EventEmitter.

@Output is a component decorator that becomes the output for the parent component and EventEmitter is something that can propagate the event from the child component to the parent component. In the parent, we will create a function to receive the message and set it equal to the message variable. In the child, we declare a messageEvent variable with the Output decorator and set it equal to a new event emitter.

Sharing Data via @Output() and EventEmitter

Example of Child-to-Parent: Sharing Data via @Output() and EventEmitter

parent.component.ts


import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    Message: {{message}}
    
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {

  constructor() { }

  message:string;

  receiveMessage($event) {
    this.message = $event
  }
}

child.component.ts


import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
      Send Message
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  message: string = "Hola Mundo!"

  @Output() messageEvent = new EventEmitter();

  constructor() { }

  sendMessage() {
    this.messageEvent.emit(this.message)
  }
}

We create a function named sendMessage that calls emit on this event with the message we want to send. Lastly, we create a button to trigger this function. The parent can now subscribe to this messageEvent that’s outputted by the child component, and then run the receive message function whenever this event occurs.

4. Child-to-Parent: Sharing Data via ViewChild

ViewChild allows one component to be injected into another, giving the parent access to its attributes and functions.

There's an issue that the child won’t be available until after the view has been initialized. Therefore, we need to implement the AfterViewInit lifecycle hook to receive the data from the child.

parent.component.ts


import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";

@Component({
  selector: 'app-parent',
  template: `
    Message: {{ message }}
    
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {

  @ViewChild(ChildComponent) child;

  constructor() { }

  message:string;

  ngAfterViewInit() {
    this.message = this.child.message
  }
}

child.component.ts


import { Component} from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  message = 'Hola Mundo!';

  constructor() { }

}

3. Unrelated Components: Sharing Data via a Service

A shared service acts as a central point for data manipulation and communication between components. Components can share data by injecting and accessing the service.

In the service, we create a private BehaviorSubject that will hold the current value of the message. We define a currentMessage variable to handle this data stream as an observable that will be used by the components. After that, we create a function that calls next on the BehaviorSubject to change its value.

The parent, child, and sibling components all receive the same treatment. We inject the DataService in the constructor, then subscribe to the currentMessage observable and set its value equal to the message variable.

Example of Unrelated Components: Sharing Data via a Service

data.service.ts


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

@Injectable()
export class DataService {

  private messageSource = new BehaviorSubject('default message');
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(message: string) {
    this.messageSource.next(message)
  }

}

parent.component.ts


import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-parent',
  template: `
    {{message}}
  `,
  styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit, OnDestroy {

  message:string;
  subscription: Subscription;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.subscription = this.data.currentMessage.subscribe(message => this.message = message)
  }
  
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

sibling.component.ts


import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-sibling',
  template: `
    {{message}}
    New Message
  `,
  styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit, OnDestroy {

  message:string;
  subscription: Subscription;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.subscription = this.data.currentMessage.subscribe(message => this.message = message)
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  newMessage() {
    this.data.changeMessage("Hello from Sibling")
  }

}

The SiblingComponent is responsible for storing the shared data and providing methods for setting and retrieving it. Both components can inject the service and make use of its methods to access the data. This creates a two-way data flow between all components that make use of the service.

Read More:

Summary

Sharing data among Angular components is essential for developing dynamic apps. We explored four approaches: Parent-to-Child via @Input, Child-to-Parent via @Output() and EventEmitter, Unrelated Components via a shared service, and ViewChild. Each method provides distinct methods to create excellent interaction, allowing your Angular components to operate together perfectly.

FAQs

'Property binding' & 'event binding' are two methods for passing data into a component. Data & event change detection in Angular is done top-down, from parent to children. For Angular events, however, we can adopt the DOM event conceptual model, in which events flow bottom-up from child to parent.

They are different. You use @Output if you want to "listen event", and ViewChild if you want to obtain the variables or execute one of the child's functions. Use @Output for drop-down sounds that you want to know when you alter the dropdown (you want to listen to an event).

EventEmitter is used for sending custom events from a child component to its parent component. When a button on a child component is clicked, for example, the child component uses an EventEmitter to notify the parent component of the button click.

Data sharing between sibling components: Points 1 and 2 can be used to share data between siblings. To begin, use an output decorator and an EventEmitter to transfer data from the child to the parent. When data is accepted in the parent component, it is shared with another child component via the Input decorator.

Take our Angular skill challenge to evaluate yourself!

In less than 5 minutes, with our skill challenge, you can identify your knowledge gaps and strengths in a given skill.

GET FREE CHALLENGE

Share Article
About Author
Deep Gautam (Technical Manager, Full Stack Developer)

He is a Technical Manager, Full Stack Developer, Author and YouTuber(DotNet Techy). He has more than 10 years of industry expertise on Angular, .NET, ASP.NET, WEB API, MVC and .NET Core. He is passionate about learning and sharing new technical stacks.
Accept cookies & close this