Since I wrote (and struggled) about Passing a custom Angular property to child components, I thought it could be helpful to share the other way around: Passing data from child to parent component in Angular
So, here is another 3-step process to follow to pass data from a child to a parent component in Angular.
As in the previous post, for the sake of simplicity, we call the parent component Parent and the child component Child. If you prefer a more practical approach, check out this practical example to get a better understanding.
Here are the three steps to pass a property to a child component:
1. Prepare Child component to emit data
The Angular documentation says "The @Output() decorator in a child component or directive lets data flow from the child to the parent." This is exactly what we want.
Furthermore, we need to know that the child component uses the @Output() property to raise an event (by using an EventEmitter) to notify the parent of the change.
- @Output() is a decorator that marks a class field (that has to be named) as an output property.
- EventEmitter emits custom events.
// Child.ts
...
export class InputBookComponent implements OnInit {
@Output() bookTitleCreated = new EventEmitter<{ title: string }>();
bookTitle: string;
...
onAddTitle() {
this.bookTitleCreated.emit({ title: this.bookTitle });
}
}
At this point, Child.ts emits data through an event every time the user clicks on the "Add Title" button that we added in Child.html.
// Child.html
<div>
<input type="text" placeholder="Write a title" [(ngModel)]="bookTitle">
<button (click)="onAddTitle()">Add Title</button>
</div>
2. Bind Property in Parent Component template
We need to instruct the Child selector in the Parent template (i.e. parent.html) to listen to this event and do something with it.
We will use event binding (see the Binding a click event paragraph) in the Child selector in the Parent template so that the selector listens for and responds to the event coming from the Child.
// Parent.html
...
<child-selector (bookTitleCreated)=onBookAdded($event)></child-selector>
The event we are listening to is bookTitleCreated and once the selector detects that event, it calls onBookAdded() method, passing $event to the method itself.
The Parent is now aware of the event but we need to create onBookAdded() method in Parent.ts to use the data (coming from the input element in Child.html) and store it into a variable.
3. Use Property in Parent Component class
In Parent.ts, we add the method onBookAdded() that receives some data (in our case, in the shape of an object with a key named title and a value of type string).
We concatenate that object to favBook using the contact method.
// Parent.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'BindingUp';
favBooks = [
{ title: 'Principles' },
{ title: 'The Story of Success' },
{ title: 'Extreme Economies' },
];
onBookAdded(eventData: { title: string }) {
this.favBooks = this.favBooks.concat({
title: eventData.title,
});
}
}
Conclusions
Feel free to check out this practical example.
Otherwise, remember the three steps:
- Prepare Child component to emit data
- Bind Property in Parent Component template
- Use Property in Parent Component class
Finally, there is another way that might be easier: using Angular Services
Top comments (0)