This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "EventEmitter Demonstration" Lesson
>> Lukas Ruebbelke: So what I will do for a demonstration, let's do one more output. Output, remember that,
>> Lukas Ruebbelke: Metadata or decorators are functions. So don't forget your parentheses. And let's just say jammin. Now we'll go new EventEmitter().
>> Lukas Ruebbelke: And then let's go to our items component.html. And so now that I've created an output called jammin, how do I bind to that?
>> Speaker 3: They're in jammin?
>> Speaker 2: Jammed?
>> Lukas Ruebbelke: We're jammin.
>> Speaker 3: Banana jam. It's kinda neat because you can look at the parent and see everything that it's capable of doing.
>> Lukas Ruebbelke: Yes I mean we are looking, like this is the contract. That's what I love. It's like input, output, output, output rr this is what this takes.
[00:01:05] And you can see, so.
>> Lukas Ruebbelke: We're just gonna do something nonsensical. Let's go into our items component
>> Lukas Ruebbelke: In my mind I'm trying to think of like if I was Jamaica and how would I actually type it, anyways. So just in your mind when you read this do it with a Jamaican accent please, okay?
[00:01:50] So jammin.
>> Lukas Ruebbelke: Jammin.
>> Lukas Ruebbelke: So, the question is how do we trigger that?
>> Lukas Ruebbelke: We need to go to our list component.
>> Lukas Ruebbelke: And,
>> Lukas Ruebbelke: I don't know, (mouseenter).
>> Lukas Ruebbelke: What's the output?
>> Speaker 2: jammin.emit.
>> Speaker 3: Binding.emit and data. Item, I don't need to put anything into it.
>> Lukas Ruebbelke: I mean, I don't really have, but I'll send the event in, just to see what happens.
[00:02:44] And actually, let's just go back here.
>> Lukas Ruebbelke: So I'm getting an undefined, and the reason being. Let's go back to items component and I'm not passing the event in. Let's do this one more time.
>> Lukas Ruebbelke: You notice here, that because I'm just sending a dollar event and actually nothing specific, that I'm getting essentially the dom event.
>> Lukas Ruebbelke: Okay, makes sense?
>> Lukas Ruebbelke: Now, let's just do an input and then we'll have lunch. So let's think of an input here. So we're passing in items, I don't know
>> Lukas Ruebbelke: secretMessage,
>> Lukas Ruebbelke: Like so. And now that we've created an input the secretMessage it's now available in the template.
>> Lukas Ruebbelke: secretMessage. Yay!
>> Lukas Ruebbelke: Let's go to items component.
>> Lukas Ruebbelke: Get over here. So being that we want to input this
>> Speaker 2: Square bracket.
>> Lukas Ruebbelke: Good, love it. secretMessage, the fact that the ID picks that up is tight. And let's go 'myMessage'.
>> Lukas Ruebbelke: And then from here, let's do something totally irresponsible.
>> Lukas Ruebbelke: Ng model,
>> Lukas Ruebbelke: And here's the question.
>> Lukas Ruebbelke: What do I do here? I need this to be two way.
>> Speaker 3: Banana in the box.
>> Lukas Ruebbelke: Banana in a box. I'll take it.
>> Lukas Ruebbelke: And then let's go ahead and just set this property here. You can tell what I'm thinking about.
[00:06:11] Lunch is served.
>> Lukas Ruebbelke: But, whoa, why is this happening?
>> Lukas Ruebbelke: Notice when I change it here.
>> Speaker 2: [CROSSTALK] It's input.
>> Lukas Ruebbelke: So,
>> Lukas Ruebbelke: Not so fast.
>> Lukas Ruebbelke: Let me elaborate. Let's go back to our items component.
>> Lukas Ruebbelke: Man I just love this h1 tag.
>> Lukas Ruebbelke: Let's make sure that we do this correct.
[00:06:54] So down here.
>> Lukas Ruebbelke: This right here, and this right here, what's happening? That's two way data binding.
>> Lukas Ruebbelke: Or rather, let me rephrase that. What's happening in the input is two way data binding. But what is happening from here and this is important to make this distinction, is because we have two way data binding between the component and the template.
[00:07:21] When we update the template, it updates the property on the component, but because then we have one way data binding, essentially interpolation on the top or property binding into our sub components. That when that property changes at the component, so remember component to template, when then property updates it gets sent in, or rather it updates the child component.
[00:07:51] Cuz we're bound to it. So we're using two-way data binding to update it from the template back to the model or to the component class. And then when that updates, because we've bound to it here, it updates as well. And so this is how you get, or one of the ways you achieve a unidirectional data flow.
[00:08:12] Because ultimately, what you want is not only to minimize state, but you wanna get your state moving in a single direction. So state flows down and events flow up, which with inputs and outputs like this is perfect. We have state coming in, we have events going out. And so this concept, when we get into like reactive data management.
[00:08:38] When we start talking about these things like how do you architect an application to handle not only state but communication. This concept of inputs and outputs, state falling down, events flowing up, not only minimizes state because if we go here,
>> Lukas Ruebbelke: Into the component itself. How much internal state do we have?
[00:09:04] We're not storing other than just is really a conduit to the template. We're not storing state. We're really just reflecting state.
>> Lukas Ruebbelke: And so now we have these components that are not only stateless but we can look at this component as we breathe life into it. And we know the direction that data is going in and we know the direction that events are coming out.
[00:09:39] And so, visually we can look and very quickly understand, data in, events out.
>> Speaker 5: Hans is taking you to task.
>> Lukas Ruebbelke: Yes, so I think Hans is really offended by the fact that I'm calling omit in the template and
>> Lukas Ruebbelke: I am going to say that we can agree to disagree on that.
[00:10:15] I think that calling into the template as opposed to abstracting that out into the controller or the component class is, there's no benefit to that. Like you're not getting a performance gain and I think as well, especially when you start to get into observables, is that you'll actually consume things directly right off the service in your template.
[00:10:43] So I think that at least for me in the religious sense that I think just doing output.admit, I think it's much less prone to error than actually just creating a method to pass that through. We're getting a request to see where you called the emit, just to see it in a template again.
>> Lukas Ruebbelke: Right here.
>> Lukas Ruebbelke: So just to for the sake of conversation, if we were gonna do this differently.
>> Lukas Ruebbelke: The solution to this would be to handleClick($event)
>> Lukas Ruebbelke: selected.
>> Lukas Ruebbelke: And then from here-
>> Speaker 3: Think you need the emit.
>> Lukas Ruebbelke: Yeah.
>> Speaker 3: Yep.
>> Lukas Ruebbelke: Right, so I feel like for the sake of keeping a method call out of the template then essentially what we're doing is we're introducing even more complexity to avoid that.
>> Lukas Ruebbelke: And so this would be one of those things where, and so there are cases where you would wanna capture the event. Maybe you wanna do some quick transformation logic as it goes out the door. So I'm not saying don't do this. But I think that introducing additional code volume, to essentially a function to call a function, I have a hard time justifying that.
[00:12:40] I mean cuz this function does absolutely nothing other than really just call essentially a function. And so this is one of these things where, Hans, if we ever meet in real life, I hope we're still friends, and a high-five. But personally, this doesn't offend me. Cuz I think actually the alternate is actually, I think a little bit more complex.
[00:13:02] And I prefer not to introduce code volume into my templates, or rather into my component classes. Yes?
>> Speaker 6: So in terms of testing then with optional and required senses, if I misspelled jammin as jamming somewhere else, it'd be like no harm no foul, I'd just never hear about an event and-
>> Lukas Ruebbelke: Yep, it would just fail silently.
>> Speaker 6: [CROSSTALK] No TypeScript error? No Angular errors?
>> Lukas Ruebbelke: Well, let's see. So TypeScript actually might throw something.
>> Lukas Ruebbelke: Let's go into our Items component. So now I just went from I'm Jamaican to
>> Lukas Ruebbelke: I am from the midwest.
>> Lukas Ruebbelke: Nothing, so it's just gonna be I don't recognize this, I'm not doing anything.
>> Speaker 6: Yeah it's still triggered, okay.
>> Lukas Ruebbelke: What's that?
>> Speaker 6: Well type in the-
>> Lukas Ruebbelke: So now this is something entirely different.
>> Speaker 6: Right.
>> Lukas Ruebbelke: If I go down here.
>> Speaker 6: Yeah it's flawed.
>> Lukas Ruebbelke: So that's not working.
>> Speaker 6: Yep.
>> Lukas Ruebbelke: Anymore questions?
>> Speaker 6: Can you explain in this view where that dollar event is coming from?
>> Lukas Ruebbelke: So this is generated from the EventEmitter. And so it contains by default, information about the dom event, but because we're passing something in then
>> Lukas Ruebbelke: In this case like selected then this just gets captured as essentially the item that we're passing in.
>> Speaker 6: So, can I pass two parameters in, to [CROSSTALK]
>> Lukas Ruebbelke: So now we're into murky territory, of which, I do not understand, because I've not been able to reasonably,
>> Lukas Ruebbelke: Figure this out. So I think you can do, I've tried this before. Let's just see what happens, test. We'll do a test parameter. Then we'll go into our items component.
>> Lukas Ruebbelke: SelectItem test
>> Lukas Ruebbelke: And,
>> Lukas Ruebbelke: This may be something we have to geek out over lunch, but this is one of these things where if you don't have item, it still gets called, and it's still in there, and so I really get, it's interesting. Is it a DOM event?
[00:16:27] What do you pass in? What if you need both? How do you handle that? Let's go here. And, yeah. So it's undefined. So I think what you have to do is actually, I remember now. The only way I've been able to get this to work is to actually create a custom object.
[00:16:44] Essentially, an event property with additional payload that you want on it. So as far as I know, I think it just takes a single parameter. I can verify that against the docs but. We had this question before of what if you need the event information and some payload is then.
[00:17:00] At that point what I would probably do is not call it directly in the dom but I would actually then pull that into the component class.