How To Pass Data From Child To Parent Component
In this article, We will learn how to pass data from a child component to a parent component in Angular. We looked at how to transmit data from the parent component to the child component by changing its input property in the last article. A parent can interact with the child via a local variable or call @ViewChild on the child, or the child can communicate data to the Parent by raising an event. In this essay, we'll look at all of those possibilities.
Pass data from Child to parent component
The parent component can interact with the child component in three different ways.
Parent listens for child event
An EventEmitter Property is exposed by the Child Component. The @Output decorator has been applied to this Property. The event is raised when the Child Component needs to communicate with the parent. The Parent Component is aware of the occurrence and reacts accordingly.
EventEmitter Property
To Raise an event, the component must declare an EventEmmitter Property. The .emit() method can be used to emit the Event.
For Example
countChanged: EventEmitter<number> = new EventEmitter()
Then, as seen below, call the emit method, supplying whatever data you want to transmit.
this.countChanged.emit(this.count);
@Output Decorator
How to Pass data to parent component using @Output
- Declare and instantiate a property of type EventEmitter.
- Add a @Output Decorator to it.
- Raise the event and pass it the data you want.
- Using Event Binding, connect to the child component and listen for child events.
- Define the function that will handle the event.
Passing data to parent component Via Events
import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'child-component', template: `<h2>Child Component</h2> <button (click)="increment()">Increment</button> <button (click)="decrement()">decrement</button> current count is {{ count }} ` }) export class ChildComponent { @Input() count: number; @Output() countChanged: EventEmitter<number> = new EventEmitter(); increment() { this.count++; this.countChanged.emit(this.count); } decrement() { this.count--; this.countChanged.emit(this.count); } }
import { Component, Input, Output, EventEmitter } from '@angular/core';
We have two buttons in the inline template: increment and decrement. In addition, we show the current count.
@Component({ selector: 'child-component', template: `<h2>Child Component</h2> <button (click)="increment()">Increment</button> <button (click)="decrement()">decrement</button> current count is {{ count }} ` })
@Output() countChanged: EventEmitter<number> = new EventEmitter();
increment() { this.count++; this.countChanged.emit(this.count); } decrement() { this.count--; this.countChanged.emit(this.count); }
Parent Component
<child-component [count]=ClickCounter (countChanged)="countChangedHandler($event)"></child-component>`
countChangedHandler(count: number) { this.ClickCounter = count; console.log(count); }
The following is the whole code:
import { Component} from '@angular/core'; @Component({ selector: 'app-root', template: ` <h1>Welcome to {{title}}!</h1> <p> current count is {{ClickCounter}} </p> <child-component [count]=Counter (countChanged)="countChangedHandler($event)"></child-component>` , styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Component Interaction'; Counter = 5; countChangedHandler(count: number) { this.Counter = count; console.log(count); } }
Now, run the Application. The child raises the event whenever the increment/decrement buttons are pressed. The Parent component is alerted of this, and the counter is updated with the current value.
Parent uses local variable to access the Child in Template
Child Component
import { Component} from '@angular/core'; @Component({ selector: 'child-component', template: `<h2>Child Component</h2> current count is {{ count }} ` }) export class ChildComponent { count = 0; increment() { this.count++; } decrement() { this.count--; } }
Parent component
import { Component} from '@angular/core'; @Component({ selector: 'app-root', template: ` <h1>{{title}}!</h1> <p> current count is {{child.count}} </p> <button (click)="child.increment()">Increment</button> <button (click)="child.decrement()">decrement</button> <child-component #child></child-component>` , styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Parent interacts with child via local variable'; }
<child-component #child></child-component>` ,
You may now use the local variable to refer to the child component methods and properties across the template, as seen below.
<p> current count is {{child.count}} </p> <button (click)="child.increment()">Increment</button> <button (click)="child.decrement()">decrement</button>
Parent uses a @ViewChild() to get reference to the Child Component
For example,
child: ChildComponent;
Parent Component
import { Component, ViewChild } from '@angular/core'; import { ChildComponent } from './child.component';
@ViewChild(ChildComponent) child: ChildComponent;
increment() { this.child.increment(); } decrement() { this.child.decrement(); }
<h1>{{title}}</h1> <p> current count is {{child.count}} </p> <button (click)="increment()">Increment</button> <button (click)="decrement()">decrement</button> <child-component></child-component>
The following is the entire app.component.ts file:
import { Component, ViewChild } from '@angular/core'; import { ChildComponent } from './child.component'; @Component({ selector: 'app-root', template: ` <h1>{{title}}</h1> <p> current count is {{child.count}} </p> <button (click)="increment()">Increment</button> <button (click)="decrement()">decrement</button> <child-component></child-component>` , styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Parent calls an @ViewChild()'; @ViewChild(ChildComponent) child: ChildComponent; increment() { this.child.increment(); } decrement() { this.child.decrement(); } }