DEV Community

Cover image for Passing data from child to parent component in Angular
Lorenzo Zarantonello for This is Angular

Posted on • Updated on • Originally published at vitainbeta.org

Passing data from child to parent component in Angular

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 });
  }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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,
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Conclusions

Feel free to check out this practical example.

Otherwise, remember the three steps:

  1. Prepare Child component to emit data
  2. Bind Property in Parent Component template
  3. Use Property in Parent Component class

Finally, there is another way that might be easier: using Angular Services

Top comments (0)