Background
In the last post, we saw how we can create nested components in Angular -
We also saw a few other angular things - links creating a new App, using Angular CLI, understanding project structure etc. All the links are in the related links section at the bottom. In this post, I will show you how to pass data from parent component to child component and listen for data to be passed from child to parent.
I am going to continue using previous code example that we have built so far. So if you need additional guidance before we start with this code, look up the previous post that talks about building nested components.
Passing data between the nested component in Angular
At this point, you should have a parent component called NewEmployeeComponent and a child component called SubempComponent. Child component just has a static HTML saying that subcomponent works. And it gets rendered as part of the parent component. All of this works and we saw it in the last post. If you do have a question till here I would recommend to go back and read my previous post -
Now let's add some input and output properties in the child component. Your child component code should look like below -
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-subemp', templateUrl: './subemp.component.html', styleUrls: ['./subemp.component.css'] }) export class SubempComponent implements OnInit { @Input() department:string; @Input() designation:string; @Output() joined:EventEmitter<string>; constructor() { this.joined = new EventEmitter(); } ngOnInit() { console.log("SubempComponent initialized"); } onButtonClick = function(event) { console.log("Button clicked. Emitting now!") this.joined.emit("Joined department " + this.department + " with designation " + this.designation); } }
Notice here that department and designation are two parameters which are input and are of type string. So we would expect the parent component to send it to this child component. Next, we have an output parameter called joined which is an EventEmitter. Parent component which creates this child component can catch and handle this output and we will see how in a moment. Finally, we have a function onButtonClick that actually emits a string saying that the button was clicked with the particular designation and department. We will now see when this function will get called. But essentially once this function is called we emit the string which the parent component can intercept and handle.
Now let's see child components HTML code -
<h1>This is sub components heading</h1> <p> Yay! subemp works! Department : {{department}} <br/> Designation : {{designation}} <br/> <button (click)="onButtonClick($event)">Click to join!</button> </p>
From the previous version of the code, I have just added lines to print department, designation and a button on click of which we call function onButtonClick which we just saw above. This function will, in turn, emit the event that will be caught and handled in the parent. We will now see changes in parent component and once done we will execute our code and see it in action.
Make changes to parent component typescript file so that it looks like below -
Notice that the only new change here is a new function called childClickedButton that we will use to catch and handle the output of child component we say above.
Now make changes to the parent's HTML file so that it looks like below -
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-new-employee', templateUrl: './new-employee.component.html', styleUrls: ['./new-employee.component.css'] }) export class NewEmployeeComponent implements OnInit { name: string; age: number; constructor() { } ngOnInit() { this.name = "Aniket"; this.age = 27; } childClickedButton = function(event) { console.log("Child component clicked. event : " + event); } }
Notice that the only new change here is a new function called childClickedButton that we will use to catch and handle the output of child component we say above.
Now make changes to the parent's HTML file so that it looks like below -
<h1>Welcome to the Employee portal</h1> <h3>Name : {{name}}</h3> <h3>Age : {{age}}</h3> <app-subemp [department]="'IT'" [designation]="'Software developer'" (joined)="childClickedButton($event)" ></app-subemp> </pre>
We have changed some things in the way we add child component in the HTML file. This is how we send input to the child component and handle the output. It's called data binding. So we are essentially sending department and designation as inputs to the child component. We saw these as @input() variables in child component. Similarly, we are now catching joined which was a output and calling our user defined function childClickedButton function. So the string emitted by the child on the actual button clicked will be sent as the event to this function.
Now let's see this in action. Run the app with command -
- ng serve -o
You should see the following screen -
Make sure you go to the correct URL path to render the components. Now you can click the "click to join" button in the parent and see the console logs. You should see the following -
You can see the button click event happened which emitted the event from the child. Parent captured it and printed another console log. That's how you can configure inputs and outputs for nested angular components and pass data.