Check out a free preview of the full Angular 17+ Fundamentals course
The "Binding Outputs" Lesson is part of the full, Angular 17+ Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Mark explains how to bind to an output event in Angular, demonstrates how to use the output event in the app component, and how to handle the emitted event in the child component. They also discuss the importance of using types in Angular to ensure that the emitted event and its data are correctly handled.
Transcript from the "Binding Outputs" Lesson
[00:00:00]
>> So now, we've done all the way up to step 4, and we kinda did them together one by one. So we added our click listener, we added our handle Save. Now we've implemented car saved but we emitted the car property. So we got that cooking. Now, in app component, we gotta bind it to a car saved event.
[00:00:18]
How do I know that that's what I have to bind to? How do I know that? It's because that's the name. So when you have this output right here, you see this little part on line 45 on my screen? See, I have this output. And when I put that output there, whatever is directed to the right of that, that's gonna be the name of the event for the output that you can reference.
[00:00:37]
That is the name of it. So that's how you can always be certain, okay? How do I know what the name of the input is? It's the same rule. So it's car, because here's where I define the input, and what's right next to it is car. So now we have the carSaved output.
[00:00:52]
So now we gotta bind to it, so let's bind to it. Where do we bind to it? Where did we say we gotta do that at? We gotta bind to it. Let's see, [INAUDIBLE] value. On the listening property, duh, okay. So now, Man, this is cool. You saw I just typed that parenthesis, it's showing me everything I need to type.
[00:01:15]
Isn't that something? Isn't that something? That's special. Tell you, Angular team, we care about you. All right, and we wanna assign it this value. I already gave you this value. Wow, man, I must really care about y'all. I gave y'all all the juice, look at that. So now we got everything that we need, except for what?
[00:01:32]
What's the last step?
>> Gotta implement that.
>> Gotta implement that, that's right. And I love to hear from you all, you know why? Cuz it lets me know that you're more comfortable and that you really do believe that I'm not gonna ask you any trick questions. So here we go.
[00:01:46]
So I wanna collapse that carList. I wanna implement this. It takes something. What does this accept? This is a harder one, it's not a trick question, it's just a little bit harder, okay? Let's walk through the path. The output emits what? Let's walk through it. What does the output emit?
[00:02:12]
>> The car.
>> The car. What type is the car?
>> Car.
>> Okay, so it's a type car. So when this is emitted, I can expect this event to be a car. Okay, I know that was a little tricky, not tricky, that's the wrong word, that one's a little difficult to grock a little bit, but I get you.
[00:02:36]
So we can do this, we can say, well, the car of type car. When I get it, the last thing I need to do is just add it to my savedCarList.push. But how do I know it can actually go in that list? How can I confirm? What can I do?
[00:02:56]
I can look at the definition and see that it is an array of type car. See, the types help you along the way. When I try to talk about this to people, like the thing about this event. Anyone ever seen the small child's toy that has a block with cut out shapes?
[00:03:14]
Okay, this is that. Because if I grab one of the shapes from the ground, I can only fit it where it matches. I can only put it into that box where it matches. So here, only a car can go into this function. If I try to send a string, or if I try to put a circle, I'm sorry, a square into a round peg, it's not going to accept it.
[00:03:36]
Same thing with our type system in Angular, like with TypeScript. It only will accept a car. If I put a string, I mean, a string won't work, a number won't work, gotta be a car. So it has to be the right shape, the right shape. So now we can maintain that, ooh, caps lock.
[00:03:53]
We can maintain that whole logic this whole way through. You see, so that even helps us all the way through, because even our array, so if I said this was just string array, doesn't work anymore, Because a car is not a string. You see, so those types. So if I said this was a string, let's just say, fine.
[00:04:17]
Now that works, but something else is gonna be broken, you know why? Because I didn't say I was getting a string from the emitted event, I told you I was getting a car. So there we go. So if the typing system has felt kinda like, what's the point of it?
[00:04:40]
Hopefully, this is helping clarify all the value, because think about trying to track down that error if you didn't have types. You were expecting an object but got a string, that's complex to track down. You spend a half a day and then you're ready to go home and then you go take a shower, you're like, the types are wrong, you know what I mean?
[00:04:59]
Later on when your brain is, that's when I get my best ideas, seriously, cuz during the day, I'd be like, wow, too much stuff happening. All right, friends, we did it, we did it. How can we prove that we did it?
>> Click a button.
>> Click a button, that's right.
[00:05:17]
Let's get this Disaccord, [LAUGH] the Pocus Fjord. All right, how many cars we get? We got a lot of cars. Look at that. All right, we're doing great. We're doing great. We got those, we got those, we got those. Okay, let's just take it one step further, just for kicks and giggles.
[00:05:34]
Kicks and giggles, just so you know that this is real. So you know it's real. I'm gonna do another for loop. For savedCarEntry of saved cars. Is it savedCarList, what is it? One of two, let's get the right property. SavedCarList, okay. Yep, our savedCarList, let's do that. Let's track savedCarEntry, blah, blah, blah.
[00:06:07]
Okay, there we go, and then I'm just gonna do a little crisp p here. But guess what, it's gonna know the types. So if I type savedCarEntry, not list, entry., I got all my stuff. I got all my stuff there, it already knows. So it's make then model.
[00:06:26]
Make, and then we'll do our model. Okay, this is just a little flavor on top of this one, right, just a little extra flavor. Okay, cool, cool, cool, cool. So if I save it, so now I wanna see, there's no saved cars. So I'm gonna save one. Did I not?
[00:06:44]
What? Did I not save it? Hold on, hold on. Is it just refreshing? Hold on, let me see.
>> You gotta scroll horizontally. [COUGH]
>> Did I mess it up that bad?
>> Think so.
>> He says he think so.
>> [LAUGH]
>> Yeah, all right.
>> SaveCar is in a new section.
[00:07:03]
I think they'll show up below.
>> Yeah, but I think the way I've done it, you gotta, [LAUGH] that feels bad.
>> [LAUGH]
>> All right, let me see if I can fix this real quick. It's just the section that has that, okay, fine. I wanna move this, cuz I think if I just do this.
[00:07:22]
Yeah, sure, sure, sure, sure, sure, okay, we'll fix it. I'm just gonna move it outside of our container where the styles are, and then it'll show up right where I want it. Yeah, there you go. So let me zoom in a little bit just so you can see.
[00:07:35]
Okay, so if I do that, you see, the cars are showing up as we save them. I am not a UI engineer, friends at home, so if you're roasting me, save it, okay? All right, there you go. So I told you this was a beefy example, right? We did a lot of stuff to get this one to work.
[00:07:58]
But that was the culmination of control flow, property binding, event binding, event handling, emitting, and input. So we did a lot of stuff, you should be proud of yourself, okay? I got something for each and every one of y'all. See this, [SOUND] that's all for you all. Good job, proud of you.
[00:08:19]
Very good, very good. All right, let's get to the next. Well, before I move on, what questions can I answer? Cuz I'm sure the chat is lit up.
>> Do inputs and outputs only work one layer above or below a parent-child relationship, or can it happen when there is more than one parent component above?
[00:08:37]
>> Can you communicate inputs all the way up? Can you go all the way up or all the way down? Well, for input, from what I understand about the way it works, you would not be able to. Okay, let me type it out, cuz that'll help explain what I'm trying to say.
[00:08:55]
So let's say that you have a div up here. Okay, we're just gonna type this out, just so I can explain. So if I have my app, let's say, car component, right, and this takes a car and you send it a carEntry. Okay, so this is what you're talking about can you do.
[00:09:14]
Right, now if we have a component that's higher than this, how would you get access to the property? So in React, the way you do that is you prop drill, right? And that's weird, cuz that becomes an anti-pattern. So you don't really wanna prop drill. If you wanna share information, you use something like a service, right?
[00:09:33]
If you wanna share information with different parts of the application. That's better than trying to figure out, how do I access this component from a higher, higher component? You gotta find a better way to share the information. And the service is probably a better way, in order to inject the value that can be pulled from that child component.
[00:09:49]
Yeah, that's a better way to do that. Prop drilling is a no, no, right? Cuz then you go 16 levels down just to get a value from the top to the bottom. That's not the right way to go. Yeah, I'd say watch out for your parentheses, watch out for your square brackets.
[00:10:04]
Make sure that even your event handler has the right parentheses and brackets there, so.
>> Are the outputs just for events, or would you use it for data you're passing back? Maybe it's a property that's gonna get populated inside the logic of the component and you wanna tell the parent component, hey, this is something that you could bind to on the way out of my component.
[00:10:29]
>> So I understand your question. So you can only output through events, yeah. You can't do a property that you wanna watch, so to speak. So people have asked for this, they asked for what you're kind of describing as an observable property. So that way, if something changes, you would know that the value changed or something like that.
[00:10:51]
People have asked for that, and we're gonna offer signal inputs. And we're gonna talk about signals today so we'll get more experience. Signal inputs will solve some of that problem, because you care about when it changed. The way we'll do that is signal. But then people asked for what's called observables, where events will populate about the stream events that happen to that property.
[00:11:14]
Yeah, but we're not gonna do that, we're gonna do signal inputs instead. Good question, that's a super question. You a genius? That was happening, cuz that was a good question.
>> You mentioned services.
>> Yes
>> Are we gonna get into services later? Are they context in React or some kind of data store?
[00:11:36]
>> Good question, we are gonna get to services very soon. And then if it's context, I don't know cuz I don't remember what context is. So [LAUGH] I don't remember what that does. Context, is that the property, sorry, the tag where you can say, this thing is available to everyone who's a child?
[00:11:54]
>> Yeah.
>> Yeah, no, it's not like that. No, no, no, no, no, a service is more like a service that you would see in traditional application architecture. So you say there's a service that holds some value, some data, and you call that service to get that data.
[00:12:09]
That's how you can share your data around your application. And we're gonna do that. That's a great question, so let's get closer to doing that. We're just wrapping up this example for inputs, outputs. And I'll just quickly go through the steps one more time, just to make sure that we're all on the same page.
[00:12:26]
The first thing that we did was that we created our app listing component, and then we moved all of the content over there. So we reference it here on line 13. In that component, we defined an input of type car in the listing component. And we define an output, which is in the event emitter, which means it sends up events and it sends up of type car.
[00:12:50]
And then we handle the event, so we bind to that event with addCarToSaved. And this special $event, that's how we can know what was sent from our event. Because sometimes you may event, sorry, you may emit that something happened, but you don't have any value, right? You're just like, yeah, this thing happened.
[00:13:09]
The person interacted with the application, but there's no value for you to know about. So you can just have an empty event emitted, so to speak, where you don't emit anything, okay? And then we have our event handler where we add to the list down here at the bottom.
[00:13:22]
But if we're over here, there's a couple of things to take note of. Got our input set as required, and we say it won't be no for the car. We got our output. We called it carSaved, and we said it's an event emitter of type car which tracks, because that's what we saw in our app.component.ts, what TypeScript was telling us that it knew about this component.
[00:13:46]
And then, here in the handleCarSaved, just so that way, cuz there's a few events happening at the same time. Let me just make sure I clarify this one. This one is just for our button, so we can trigger the emission, right? That's what we're trying to do, is to get the emission to happen.
[00:14:03]
So we just added a button called handleCarSaved. But that's not a part of the output, so to speak. It's completely separate. This could be anything, but we just needed a way for this emission to happen. Another thing that we might have been able to do was, can I do this?
[00:14:18]
Let's see, let's see if we could have even done this. I don't know if we could have done this or not. Let me try something. Let me just experimentation, okay? So it kinda works. Okay, so that also works. So that might have helped a little bit to kinda remove one of the events.
[00:14:34]
But this isn't really necessarily the best practice. Let me tell you why. What if you have multiple things to do before you hit the emission? So that's why I had a function there, because if I had to maybe adjust some data, do some other tasks, you can't fit them all in one liner.
[00:14:52]
In our case, we could've fit it into one liner, that might've made it a little clearer, right? So we got a button that we're saying, hey, you click the Save car button, we're gonna just do this emission. So maybe that helps a little bit to clarify where everything puts into place.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops