Methods to Share Data Between Angular Components

Methods to Share Data Between Angular Components

08 Mar 2024
Advanced
206K Views
15 min read

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:

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.

Read More: Understanding Angular Components

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

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.

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

Q1. How do you send data to an Angular component?

'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.

Q2. What's the difference between @output & @ViewChild?

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).

Q3. How does Angular's EventEmitter work?

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.

Q4. What is the best approach to transfer data amongst Angular siblings?

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 free angular skill challenge to evaluate your skill

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

GET CHALLENGE

Share Article
Batches Schedule
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.
Self-paced Membership
  • 22+ Courses
  • 750+ Hands-On Labs
  • 300+ Quick Notes
  • 55+ Skill Tests
  • 45+ Interview Q&A
  • 10+ Real-world Projects
  • Career Coaching
  • Email Support
Upto 66% OFF
KNOW MORE..

To get full access to all courses

Accept cookies & close this