Angular Input & Output Decorator

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

  • The @Input decorator allows a component to read data from a parent component to a child component by defining a variable in the child component with the @Input decorator. 
  • The @Input decorator is specified in the '@angular/core' module, and we can use it by importing from there.
  • Syntax to define Input decorator is :
    @Input() variableName :<dataType>
    
  • So here I defined dataFromParent variable using as @Input decorator to read data from the parent component
  • Now in the parent component, I use a child component selector here [dataFromParent]="passDataFromParent" to pass data to the child component 
  • The child component read that in dataFromParent property and uses it in the template to display data.

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

  • The @Output decorator allows a component to pass(emit) data from a child component to a parent component by defining an EventEmmiter in the child component with the @Output decorator.
  • The @Output decorator is specified in the '@angular/core' module, and we can use it by importing from there.
  • Syntax to define Output decorator is :
    @Output() newItemEvent = new EventEmitter<dataType>();
  • So first In the child component, I defined @Output decorator as @Output() onClick = new EventEmitter(); 
  • Now here in the child component template using the select button I trigger passDataToParent(item) method.
  • And using onClick EventEmitter I emit that output event and pass data to the parent component.

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.