How to communicate and share data from parent component to child component (@Input decorators) and from child component to parent component (@Output decorators).
Introduction
- Angular provides data sharing decorators to communicate between the parent component to the child component using the @Input decorator and from the child component to the parent component using the @Output decorator,
- Here @Input() property is writable and an @Output() property is observable.
- So let's understand more by using the examples below.
@Input decorator
parent.component.html
<div class="wrapper">
<app-child
[dataFromParent]="passDataFromParent"
></app-child>
</div>
child.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ChildData } from '../../SAMPLE_DATA';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
})
export class ChildComponent implements OnInit {
@Input() dataFromParent!: ChildData[];
}
child.component.html
<h2>Child Component</h2>
<div class="child-wrapper">
<ng-container *ngFor="let item of dataFromParent">
<mat-card align="center">
<mat-card-content> {{ item.name }} </mat-card-content>
<button
mat-raised-button
color="primary">
Select
</button>
</mat-card>
</ng-container>
</div>
We show passing data from the parent component to the child component.
The output of @Input decorator example
As you can see here, I clicked any food products and passed that data from the parent component to the child component and the child component displayed those data in card format.
![@Input decorator]()
@Output decorator
child.component.html
<h2>Child Component</h2>
<div class="child-wrapper">
<ng-container *ngFor="let item of dataFromParent">
<mat-card align="center">
<mat-card-content> {{ item.name }} </mat-card-content>
<button
mat-raised-button
color="primary"
(click)="passDataToParent(item)"
>
Select
</button>
</mat-card>
</ng-container>
</div>
child.component.ts
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ChildData } from '../../SAMPLE_DATA';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
})
export class ChildComponent implements OnInit {
@Input() dataFromParent!: ChildData[];
@Output() onClick = new EventEmitter();
constructor() {}
ngOnInit(): void {}
passDataToParent(item: ChildData) {
this.onClick.emit(item);
}
}
- Now in the parent component template, I bind the parent method getDataFromChild($event) to the child component onClick event to get emitted event from the child component
- So Using the (onClick) output event, the parent component receives a response event from the child component in the getDataFromChild() method, stores it in the dataFromChild variable, and displays it as a Selected Item:
parent.component.html
<div class="wrapper">
<h2>Parent Component</h2>
<div class="title">
Selected Item :
<span *ngIf="dataFromChild" class="selected-item">
{{ dataFromChild?.name }}
</span>
</div>
<ng-container *ngFor="let item of sampleData">
<button
mat-flat-button
color="warn"
style="margin-right: 12px"
(click)="passDataToChild(item.childData)"
>
{{ item.name }}
</button>
</ng-container>
</div>
<div class="wrapper">
<app-child
[dataFromParent]="passDataFromParent"
(onClick)="getDataFromChild($event)"
></app-child>
</div>
parent.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ChildData, ParentData, SAMPLE_DATA } from '../../SAMPLE_DATA';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
passDataFromParent!: ChildData[];
dataFromChild: ChildData | undefined;
sampleData = SAMPLE_DATA.parentData;
constructor() {}
ngOnInit(): void {}
getDataFromChild(item: ChildData) {
this.dataFromChild = item;
}
passDataToChild(item: ChildData[]) {
this.dataFromChild = undefined;
this.passDataFromParent = item;
}
}
- If you want to pass a specific data type in the output decorator, you can do so as shown above.
The Output of @Output decorator example
As you can see here I select any food item by clicking on it, and the child component emits that selected data to the parent component, which reads that data and displays it as Selected Item
![@Ouput decorator]()
The final output
![Angular Input & Output Decorator]()
- Find the full source code here
Summary
- As you can see, this blog covers how to pass or emit events carrying data from a child component to a parent component using the @Output decorator, as well as how to send data from a parent component to a child component using the @Input decorator.
- Please let me know in the comments area if you have any questions.