You’re probably here because you are wondering how to pass data between your Angular parent and child components. This is a very important and useful functionality for any Angular application. In this post, we will talk about how to achieve this using the @Input()
and @Output()
directives.
@Input
The input directive gives us the ability to pass data from an Angular parent component to the child component. Angular provides this directive, which you can easily implement in any component. Let’s see how it works!
Let’s create our basic parent and child components for the sake of this example.
// parent-component.html
<div>
<span>This is the parent component!</span>
<app-child-component />
</div>
// parent-component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent-component',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss']
})
export class ParentComponentComponent {
public parentValue: string = "test value";
}
As we can see in the parent component above, we have the app-child-component
nested inside the parent component’s HTML. We want to pass parentValue
to the child component so it can access its value.
We will need to do the following in the child component to do this. Here we will use the @Input()
directive.
// child-component.html
<div>
<span>This is the child component!</span>
<span>The parent value is: {{value}}</span>
</div>
// child-component.ts
import {Component, Input} from '@angular/core';
@Component({
selector: 'app-child-component',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss']
})
export class ChildComponentComponent {
@Input() public value: string = "";
}
In the child component’s TypeScript file, we import the @Input()
directive from the @angular/core
library. We can now prefix the variable with @Input()
to store the parent value.
We can now use that value inside our child component as seen in the html above. Now let’s update the parent component to pass this value to the child.
// parent-component.html
<div>
<span>This is the parent component!</span>
<app-child-component [value]="parentValue" />
</div>
By adding the @Input()
tag in the child component, you can pass the parentValue
to the child component through the value
property. The value
corresponds to the variable you created that follows the @Input()
directive.
Now the child component can access the parent value and use it inside the component. That is how we can pass data from a parent to a child component!
@Output
Now that we can pass data from the parent to the child, let’s look at how we do that in the opposite direction. This can be done with the @Output()
Angular directive.
Let’s add to our child component code above to demonstrate this functionality.
// child-component.html
<div>
<span>This is the child component!</span>
<span>The parent value is: {{value}}</span>
<button (click)="passValueToParent()">Send</button>
</div>
// child-component.ts
import {Component, EventEmitter, Input, Output} from '@angular/core';
@Component({
selector: 'app-child-component',
templateUrl: './child-component.component.html',
styleUrls: ['./child-component.component.scss']
})
export class ChildComponentComponent {
@Input() public value: string = "";
@Output() public childEvent: EventEmitter
= new EventEmitter(); protected passValueToParent(): void { this.childEvent.emit('test value') } }
In our typescript file above we are doing a couple of things. First, we are importing the @Output()
directive from the @angular/core
library. We can then use it similarly to how we use our @Input()
directive. The only thing different here is that to pass the value to the parent we need to use something called an EventEmitter
.
You use an event emitter to send or emit a value to the parent component where your child component is nested. In our example above we create an EventEmitter<string>
because the value we want to send to the parent is a string
value. You can change this type depending on the value you emit.
Next, we call the event emitter to emit the value. We create a function called passValueToParent()
that uses the event emitter to emit the value. Here we emit the string value test value
.
We added a button to the HTML that triggers the event emitter when clicked. The button sends the value to the parent component when pressed. Next, let’s update the parent component to receive this value emitted by the child.
// parent-component.html
<div>
<span>This is the parent component!</span>
<app-child-component [value]="parentValue" (childEvent)="childValue = $event" />
</div>
// parent-component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent-component',
templateUrl: './parent-component.component.html',
styleUrls: ['./parent-component.component.scss']
})
export class ParentComponentComponent {
public parentValue: string = "test value";
public childValue: string = "";
}
To the HTML above, we add the prop (childEvent)="childValue = $event"
. In this case, we use the (childEvent)
prop to indicate that this is an event being emitted from this component. The prop’s name, childEvent
, comes from the variable you named in the child component for the @Output()
event emitter.
Inside that prop, we can directly assign the value emitted by the @Output()
directive to a variable in the parent component through the $event
value. This event fires as soon as the child component emits the value from the event emitter.
With that, we have successfully passed a value from the child to the parent component!