When passing data up to a parent component with the Angular @Output() decorator, you’ll need to set up an event handler in the parent, and then emit events from the child component whenever your data changes.
In the article: “Angular Child to Parent Communication with @ViewChild()”, I detailed two ways in which data can be passed from a child component to a parent component. In this article, I will cover the other approach, which leverages the @output() decorator.
When we walked through the steps for the @ViewChild() decorator, we saw that the majority of the setup work happens in the parent component. Here, with the @output() decorator, things are a bit different. For the most part, the required steps are spread out across the parent component, the parent template and the child components. I was actually a little surprised to see how intimate the relationship between the child and parent components / templates are. On a high level, the data communication starts with event handlers in the parent component. Then, in the parent component’s template, we specify event handlers for each property that we want to pass-up to the parent component. And finally, in the child component, there is a two-step process.
First, we use the @Output() decorator to create an instance of EventEmitter. Next, we set up methods in the child component that match the naming convention used in the parent component template (see Examples # 2 and # 3 below). It’s a surprisingly close relationship between the various pieces of the puzzle, given Angular’s declarative-focused syntax. Let’s take a look at some code examples.
Full Working Example Code
You can clone the full working example code here: https://github.com/kevinchisholm/video-code-examples
- Go to this folder in your terminal: angular/components/@output
- Follow the directions in the readme
The Parent Component – Example # 1
In Example # 1 we have the parent component. Here, the userName and userPhone properties will be utilized in Example # 2, to set up the binding for the data that we will receive from the child components. And on line #s 11 and 15, we create methods that become event handlers. Note here that although I name each method’s lone argument “$event”, this is completely arbitrary; I could have named it anything. The key thing here is that in each of these event handlers, we update the userName and userPhone properties with the data that we receive from the child components (i.e. $event).
The Parent Component Template – Example # 2
So now, in Example # 2 we have the parent component template. As expected, we see bindings for the userName and userPhone properties. But the interesting parts happen on line #s 5, 6, 9 and 10. We’ve set up handlers for the nameEvent and phoneEvent events, and the values that we assign to these handlers match up with the methods that were defined in the parent component: nameEventHander and phoneEventHander. So, this is where the connection is made between the child and parent components. In fact, the syntax used probably looks familiar to you: (click)=”someEventHandlerName($event)”. In our code, the difference is: instead of click, we are connecting a method to a custom event (i.e. nameEvent or phoneEvent).
The Child Components – Example # 3
In Example # 3 we have the child components, and on line #s 8 and 9 we have used the @Output() decorator to create two custom events. These events are instances of Angular EventEmitter, so the nameEvent and phoneEvent properties become event emitters. Then on line #s 14 and 18, we have the onNameChange and onPhoneChange methods. In these methods, we use the emit() method of the nameEvent and phoneEvent properties, which are instances of EventEmitter. So this, of course, is where the data is getting passed up to the parent component.
The Child Component Templates – Example # 4
In Example # 4 you’ll see the code for both of the child component templates. Notice how we have set up an event handler for each text input keyup event. This is where we are assigning the onNameChange and onPhoneChange methods to those events. So what happens is: the user enters some text in either of the inputs, which triggers the onNameChange and onPhoneChange methods, which in-turn emit the custom events. That triggers the handlers in the parent component’s template, passing up the data from the child.
So, in leveraging the @output() decorator, keep in mind that while the differences between it and the @ViewChild() decorator are not minor, they’re also not particularly complicated, once you understand how the data communication channels are set up. This means that when you use the Angular @output() decorator, you will be adding an event handler to your parent component. That event handler will then receive data, which will allow you to update the parent component’s template with that updated data. You will also be configuring the event handler on the child component HTML element in the parent component’s template, which is where the data connection happens. And then finally, in the child component, you’ll leverage the @output() decorator to emit an event with updated data, thus allowing the data to flow up to the parent component.