Subscribing to component events with @Output - lordoftheflies/angular-essential-training GitHub Wiki
Angular has an output decorator that allows you to expose event bindings on components. We can update the media item component and make use of the output decorator to provide notifications of a delete request. Using output is similar to how you use input. First we need to import the output decorator from the @angular/core scoped package. Then we can use the output decorator to decorate a property on the component class, that we can name "delete." The difference with output is we want to set the property to an EventEmitter object. To do that, we need to import the EventEmitter, which also comes from the @angular/core scoped package. So let's go up to our import statements, and add EventEmitter to the import statement for the @angular/core scoped package. And then back down at the new property, we can set that equal to a new EventEmitter. Like the input decorator, the output decorator allows you to pass in a string value if you want to alias the property. But again, it is recommended you only use the alias if you run into a case where you need it. So we will stick with the property name of "delete" here. What we are doing here is exposing an event that can be subscribed to on our custom component, just like native DOM events. So we have this EventEmitter that we set the property to. This will allow us to emit the event, but to emit the delete event, we need to have something happen. We already have a click event wired up to the delete link in this component, which is calling the on delete method that we created. Inside of that method is where we are going to emit the output event. We do this by using the delete property that we decorated with the output decorator. The delete property, which is an EventEmitter, has a method named "emit." So we call this.delete.emit. This method expects to be called with an argument that represents data we can send back. If we didn't have anything to send back for this event, we could pass this emit call null, but it might be helpful to have our delete event return back what was requested to delete. Since the media item component class has a media item property, we can pass that back. So let's give the emit call this.mediaItem. And with that, the media item component is now wired up with an output for a delete event, using the output decorator. The last thing we need to do here is head over to the app component, where we are using the media item component, and make use of the event. So over in the app.component.html file, we can add the delete event binding to the mw-media-item element. We need to set this to a statement, so let's create a call to an onMediaItemDelete method. And since this emit callback in the media item component was being called with the media item as an argument, we can make use of a key term, $event, over here in the statement, to get access to that value. When Angular evaluates the statement, it will handle getting that emit value, and setting it into the variable, $event. So we can just use that in the statement, and pass it to the method call. So this is us in the app component telling Angular, "Hey, when this media item component emits its delete event, we want to respond to that by calling the app component onMediaItemDelete method." The output decorator allows you to do the same thing with your components, that Angular is doing with those native DOM events. One last thing. We need to flip over to the app.component.ts file, and add our onMediaItemDelete method. We know that the event from the media item component will return us a media item object, so we can add a parameter named mediaItem to the signature. In an upcoming video, we'll fill out this method with the logic to delete a media item.