This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Sending Events to a Container Component" Lesson
[00:00:00]
>> Lukas Ruebbelke: So, data's coming in. And, what do we do if somebody selects an item, or they want to delete an item? How do we capture that? Well, just as we captured a click event, we can create our own custom event using output.
>> Lukas Ruebbelke: And, so let's go with selected.
[00:00:33] Typically, not always, but I prefer to use things like selected, deleted, canceled. So kind of like past tense. Like hey, this event happened. Now the difference is, you need to initialize this as an eventEmitter. So when you create an output, you initialize it as a new eventEmitter. So it stands to reason that if you have a DOM event that's emitting an event, a custom event would also need to do that.
[00:01:05] Now, one thing I will also call out is notice it's imported from angular core, but if you go down here, there's all sorts of implementations other than emitter. I think they actually pulled this off of node, but make sure that when you import this, you get the right eventEmitter.
[00:01:26]
>> Lukas Ruebbelke: Let's also do deleted.
>> Lukas Ruebbelke: VS code.
>> Lukas Ruebbelke: All right.
>> Lukas Ruebbelke: So now, we have.
>> Lukas Ruebbelke: Some events we wanna capture here.
>> Lukas Ruebbelke: So, selected. Notice, that picked that right up. selectedProject. And, it's going to take a parameter of event. So this is where it got kind of interesting earlier.
[00:02:07] And they may have updated this recently. But we'll go here. deleteProject, also event.
>> Lukas Ruebbelke: There we go. selectProject. deleteProject. But we need to trigger said event. So, on our list item.
>> Lukas Ruebbelke: We can go here. And, we'll capture the click event, at the component level. And then we'll go selected.emit.
[00:02:47] And we're just going to pass it up to project. So the difference is, that you're just firing the emit method on your eventEmitter. And then if we go down here.
>> Lukas Ruebbelke: To this delete, I'm gonna go ahead break to a new line. We'll go click.
>> Lukas Ruebbelke: And we'll go, deleted.emit.
[00:03:13]
>> Lukas Ruebbelke: Also sending the project and $event.stopImmediatePropa. Is it propo or propa? I think it's not gration, but I think that's propagation. We'll see here.
>> Speaker 2: How about Gatreon?
>> Lukas Ruebbelke: Gatreon, that's not good, superhero. [LAUGH] Propagation, you know what? If only there was a device. I think I'm good, all right.
[00:03:48] So now, instead of capturing the click and handling it in the component, we're just hooking it to the eventEmitter and emitting the event up. So if we go into our projectsComponent here, let me go ahead and let's do, I'm just gonna comment this out.
>> Lukas Ruebbelke: c.log.
>> Lukas Ruebbelke: Delete Project, project.
[00:04:27]
>> Lukas Ruebbelke: And.
>> Lukas Ruebbelke: I know what's up here somewhere, there we go.
>> Lukas Ruebbelke: Select Project.
>> Lukas Ruebbelke: Okay?
>> Lukas Ruebbelke: Let's go over here.
>> Lukas Ruebbelke: And let's see as we select this.
>> Lukas Ruebbelke: Pretty good. Also, we can delete project. This is, I think kind of what we were expecting. The difference is we're capturing, we're creating an internal eventEmitter that we're then calling emit, and essentially broadcasting that event to capture on the parent component.
[00:05:26]
>> Speaker 2: Maybe I missed it, how does the parent component catch that event?
>> Lukas Ruebbelke: So, notice here, in the parent component template, and this to me is [SOUND]. This is a thing of beauty.
>> Lukas Ruebbelke: I look at this, and I have a pretty good idea what this thing does, it's a pretty clear contract.
[00:05:57]
>> Lukas Ruebbelke: I look and immediately know, it has an input of projects, I would expect a projects list to have that. And it takes a selected event, even so selected in respond to it and delete it. So if you ever looked it like some kind of component API, I'm easy it is with jquery, a lot like, what events is this a meeting?
[00:06:18] How do I buy into this thing and do something. Well, right here.
>> Lukas Ruebbelke: We have it. This is a clear API, and so what's fascinating to me is in just a few lines of code, we're able to express exactly what this thing does and how to interact with it.
[00:06:40] And.
>> Lukas Ruebbelke: This also, I think it's pretty amazing. If we go into the project.
>> Lukas Ruebbelke: ListComponent.
>> Lukas Ruebbelke: Look at all this logic that I have laying about. False, there is no logic in here. In fact, other than its bindings, there are zero moving parts in this component.
>> Lukas Ruebbelke: So, for instance, how would you test this?
[00:07:20]
>> Lukas Ruebbelke: Or rather, how would you write a unit test for this? If a unit test is designed to test a unit of logic and there is no units of logic.
>> Lukas Ruebbelke: I feel like this is kind of like the shift from, if you remember like the old spinning plate hard drives, and if you've ever slammed your computer down in anger, and it goes boop, boop.
[00:07:38] And I also know you've got a problem versus a solid state. These are much harder to break, because there's no moving pieces. Sure, you could put bad data in, and possibly cause something weird. But, I'm pretty sure that Angular is not going to break. And so as a result, you can fairly reliably say if I have this component, and I satisfy these inputs, and I respond to the outputs correctly.
[00:08:05] This is not only extremely stable, extremely portable, but also very descriptive and self documenting what it does. And so what we have here is, I'll finish the details component in just a moment, but this is what's called a presentation component. Its a opponent that is simply designed for presentation, and then capturing events, and delegating them up.
[00:08:29] So remember, I said a component has two main responsibilities. This to me optimizes that particular goal. It's consuming the data it needs to satisfy the template. It's capturing events at the component level, or locally, or it's capturing it locally and then putting it out to the parent component.
[00:08:56]
>> Lukas Ruebbelke: And, you can very easily, I mean, without really working too hard, I could pick this up and move this to the home component. And, I could probably blow up entry module, and get the imports wrong, and waste 20 minutes but other than that like, it would be pretty good.
[00:09:19] So now what we have, is a component that just takes imports and outputs. It's for the most part like solid state if you will but then, you have a container component like the projects component. And its entire responsibility and concern, is simply to capture data and handle the fetching of data and where that comes from, so you'll notice here in getProjects.
[00:09:50] Its saying hey, remote service go get me this thing. But then once it gets it, then it's simply taking that and parsing it out or delegating it out to its presentation components, so a container component is concerned about. The implementation details of where that data is coming from, the query portion of the I would say application state, but also the command portion.
[00:10:15] So that when something happens, for instance a deleted event on the container component, it is saying I'm gonna capture this. And I'm going to delegate this out.
>> Lukas Ruebbelke: And what this does, is it allows you to create these broad container components, that is consuming just enough data, again, to satisfy its template, but it handles the implementation details.
[00:10:48] As well as with something happens at the child component level that it then broadcast that back up that is all happening is, with something happens on the projects list, it's capturing it and say, okay, I know what to do. I'll just ask the son of the server for you.
[00:11:07] And notice this are very thin methods, there's not a lot happening as it should be. So just as a matter of course, you want to favor fine-grained, single purpose methods. And so as we get into testing tomorrow, this is going to be a large recurring thing. It's when you start to break things out to serve a single purpose, then you know how very stable, very chordable and very testable pieces within your application.
[00:11:45] All right. Yes.
>> Speaker 2: So one more question, so you're passing in from the projects component template, the event, the $event with the actual method. No, so it's like project $event that actual method is taking in a project, right?
>> Lukas Ruebbelke: So, something's converting that or. It definitely expects the $event Which then can be anything.
[00:12:16]
>> Speaker 2: Anything that you emit.
>> Lukas Ruebbelke: So whatever you emit, that's being captured as an event. I believe that's probably like some defined signature somewhere else. But, since we're here, let's do this. Let's just, we'll stick with selected. Alright, so in selected, we now have event and project. Let's go into our project component, what I need to do is update this to be event.
[00:12:50] Let's go ahead and log this out. 'HELLO!', $event, if this work this would be fantastic.
>> Lukas Ruebbelke: And then in here.
>> Lukas Ruebbelke: Here we go.
>> Lukas Ruebbelke: So it might be a single parameter. Let's see what happens. I think that's actually maybe what I ran into. It's one or the other.
[00:13:32] And what on the template itself, it expect $event. But we're gonna find out. Yeah, see, you basically have one thing. But, if I go here, I can emit(project). But this is where I think I got burned. If I go like this here, and then into the project component.
[00:14:07]
>> Lukas Ruebbelke: I think it does not like this, yeah. So, what it requires because the I think is to string interpolation a $event on the template itself.
>> Lukas Ruebbelke: So she suspect two event here. And, make sure I didn't leave this in a weird spot somewhere else.
>> Lukas Ruebbelke: Just clean this up.
[00:14:38]
>> Lukas Ruebbelke: Good, good, good. All right.
>> Lukas Ruebbelke: So far, so good.