Passing Data from a Nested Component with @output
Nov 25, 2019 • 5 Minute Read
Introduction
In this guide, we're going to learn about @Output(). It is one of the most useful decorators in Angular, and it helps to send data from a child component to a parent component.
Introduction to @Output()
A decorator emits an event up to a parent component using event binding. The parent component should have a function that accepts the data emitted from the child component. It gets the data before calling the ngOnInit() method.
ngOnInit() is one of the lifecycle hooks in Angular, and it's called after the constructor() and ngOnChanges() methods. You can learn more about Angular lifecycle hooks here.
Need for @Output()
@Output() is used to interact between components. There are different types of interaction between components in Angular, but @Output() is used specifically for the interaction between parent and child components. There are various ways we can make one component interact with another component. Two of these include:
- Using services
- Using @viewChild()
However, @Output() is used if the hierarchy level between parent and child is smaller. If there is a large hierarchy, I suggest you use services.
How to Use @Output
Now we'll dive into the coding section of the guide to give you a better idea of how to use @Output().
First, we'll make two components. Fire up the cmd and go to your project folder and type the following commands :
$ ng g c components/parent-output --skipTests=true
$ ng g c components/child-output --skipTests=true
We have successfully created the components; now it's time to use the @Output() decorator.
app.component.html
<app-parent-output></app-parent-output>
In app.component.html we'll call the parent component.
child-output.component.ts
import { Component, OnInit, Output, EventEmitter } from "@angular/core";
@Component({
selector: "app-child-output",
templateUrl: "./child-output.component.html",
styleUrls: ["./child-output.component.scss"]
})
export class ChildOutputComponent implements OnInit {
@Output() demo = new EventEmitter<string>();
constructor() {}
ngOnInit() {
this.demo.emit("This is the child component");
}
}
There is no code required in child-output.component.html. We just need to send the data from the child component, which is possible by using the @Output() decorator and EventEmitter class; both of them are included in the @angular/core package.
EventEmitter is a class which is used to emit custom events and is used only with the @Output() decorator. It extends the Subject class, which is used to apply the provider-subscriber kind of communication. Subject is a part of Observable, and you can read more about it here.
In the above snippet, we have created a demo variable which is headed by @Output() and instantiated by EventEmitter. EventEmitter accepts the data type that we need to pass in pair of braces (<>). In our case, we give a string to the parent component.
Our child component is ready to emit the event, so we call the emit method, which is a method of EventEmitter class.
In the ngOnInit() method of the child component, I'll call the emit method. Data passed from the child needs to be accessed in the parent component, and for that we need event binding.
parent-output.component.html
<app-child-output (demo)="acceptData($event)"></app-child-output>
In the parent component, we've just called the child component. To access the data from the child component, we have to do event binding. Event name must be our variable name, and it is instantiated by the EventEmitter class. To accept the data that is passed from the child component, we need to define a function in the parent-output.component and call it in the app-child-output selector, as you can see in the above snippet. $event is mandatory to use as it gets the data from the child and passes it to the parent function.
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-parent-output",
templateUrl: "./parent-output.component.html",
styleUrls: ["./parent-output.component.scss"]
})
export class ParentOutputComponent implements OnInit {
constructor() {}
ngOnInit() {}
acceptData(data) {
console.log(
"this is the child data displaying in parent component: ",
data
);
}
}
In the above code, we have created a function that is called in our child component selector. data is the parameter that stores the data coming from the child component.
After we run this project, we can see the following output in the console:
You can see how data is passed successfully from the parent to the child component, and we display the output in parent-output.component.ts line number 15.
Now you have become a master of using the @Output() decorator.
SConclusion
@Output() is one of the most useful decorators in Angular, and it helps send data from a child component to a parent component. I hope you learned something new from this guide.