Check out a free preview of the full Angular 17+ Fundamentals course

The "Inputs & 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 guides the students through an example of using inputs and outputs in Angular components. They start by moving the template structure of a component to its own file and then add an input decorator to communicate with the component. They also demonstrate how to pass data into the component using property binding and fill in the component's details.


Transcript from the "Inputs & Outputs" Lesson

>> So we left off talking about inputs and outputs. Inputs let us send information into a component, and outputs are the way to send events out of the component. But both of those things, both are about the communication story, communicating with your components. So let's jump into an actual example fresh, just right now.

Let's get this next young example, 06-inputs-and-outputs. So I go back to my code, close up my previous example, let me just clean up behind. We'll clear this right up, and then I wanna go into 06. Now, this one's a little beefy, this is a beefy example. So here's what we're gonna do.

So yeah, this is an input, output and a recap. So with this example, we're gonna be leveraging all the tools that you've learned so far. So you learned how to do interpolation, you learned composition, you've learned at a high level binding, that's okay, and we learned some event handling.

So we're gonna do a lot of that stuff, yeah, it's all good. This one's a little beefy, we're gonna work on it together, though. Don't double-click these files, just single-click, if you double-click, it takes you to the edit mode. All right, we're gonna start it up. 06, we're in a 06 example.

Okay, so now we've got our saved cars. Let's make sure this is our example. I'm pretty sure this is our example. Okay, so we've got a bunch of stuff in here, a bunch of stuff, and we're gonna get it cooking. All right, so we're gonna continue our listing example, because I hinted earlier that there's a better way for us to do this example.

There's just a better way because we had so much HTML that was being repeated with that for loop, but it felt like, can we organize our code better? Well, that's a part of this activity, right? We're gonna communicate with our components and do all kinda stuff. So first, the idea to start with is to move our component template structure to the ListingComponent, and that's in listing.component.ts.

So that's where you start, and then we'll add input, so we can communicate into the ListingComponent, and then we'll reference it. So I'll give you just a minute so you just kinda start the first steps. Start with the first step of just doing the step number one. Let's knock that out, and let me go ahead.

And I'll do it with you, But we're gonna start with our first step. All right, so line 10 is where you should start from, you're gonna do your copy. I marked it out so we don't waste time or lose time on trying to figure out what to copy, okay?

So I marked it out for you, [LAUGH] not marked it, no pun intended. All right, so I'm gonna move that right out of there, okay? And then I'm gonna go into src > app > listing > listing.component, and I left you another hit. This is like, wasn't one of these you breadcrumbs because they want you to find your way home.

I want you to find your way to success on this component and with this activity, so I left you some breadcrumbs. Okay, so then I'm gonna delete the stuff that's in there and I'm just gonna make some space, and then in my space I'm gonna put what we just had.

Okay, it looks good, sounds good, sounds good. So let's see what should happen here. All right, so I'm moving a little fast, let me slow down a little bit. All right, so I'm in listing.component, so everyone can know we're in 06-input-output listing.component.ts. I've just moved in the article element of class listing, and I moved it into that file.

So I'm gonna save this, and then I'm gonna save my app.component and I'm gonna go back. And this is what I expect to see is nothing, because I haven't done, what am I missing?
>> You haven't put the reference to it back in the original template.
>> That's right, I did the import and I didn't make the reference, exactly right, those are my two steps.

So, let's make that happen. So, first thing I do, I import my ListingComponent cuz I gotta make it available in the file, and because it now is a dependency of our components, we do imports array, okay? There you go, so add it into your imports array. Okay, now, the last step, if I just do app-, and then it'll tell me what's available for me in my namespace right now.

Okay, so it knows that about the import sort of the app listing. So now if I do that, save that up, and refresh, now we're back to where we were. Okay, now we're back to where we were. And if we want, if you wanna have some fun now, I think, let's see what order I actually do this in.

Okay, you could add the input here. Yeah, so we can add the input, because there are two steps you can do here, but it might just be easier to do it one step. Let's do it one step at a time, and we'll create our input. Now our input is a decorator, so we gotta go up to line 1, and let me slow down, in listing.component.ts, going to line 1.

I'm also gonna import input. So if you did this and you added a second line and you just did input here. And did from Angular core, that is also fine, right? You could do it this way, but if I'm reviewing your code, I'll say, hey, combine those inputs, right?

So I just combined them. Yeah, all right, so let's mark, I wanna close this for a second. Let's just kinda close these we're not using, just to keep our focus in the right places. So we need to have an input, what should it be called? What should our input be called?

Anybody remember from the readme? So we've got @Input, don't forget your parentheses, and then what's the name of this property?
>> Car.
>> Car, there you go, car, good. Good, good, good. car, and what type should it be?
>> Car.
>> Of type capital Car, right, that's the type.

Okay, so you're gonna run into something here. So input called car, don't forget to import the Input decorator, but guess what you're gonna have to do? TypeScript is gonna complain. So if I save this, it's going to complain. Let me tell you why. Because car has no initializer, meaning, what's the value of this car right now?

Currently in this component, what's the value of the car?
>> Undefined.
>> Undefined, so if I access any of the properties on it, it's gonna throw an error. So TypeScript, even though this feels annoying, because you're like, I'm in the middle of something, let me finish what I'm doing before you start complaining.

It's letting you know right off the bat, look, you have not given this an initial value, and I don't know that I'm going to get an initial value, so I'm gonna throw an error, okay? So we can do one of two things, we can say that we know for sure it won't be undefined, or we can give it an initial value.

We're gonna go the former, okay? We're gonna tell it for sure, it won't be undefined, and we have the exclamation point, car! [LAUGH] No, that's called the non-null assertion operator, okay? I know super long name, let's call it the non-null assertion operator. So I'm telling TypeScript, fam, chill out, it is gonna be fine, I'm going to handle this, okay?

Don't you worry about it. But we can also get a little bit more busy here if we want. Now I didn't put this in the instructions cuz this is not super, it's not mandatory, but I can also help my developers who may consume my component, right? Because maybe I'm on a different team, right, and I'm making my component and I was like, you use it when I'm done.

I can help them out. I can also say required: equals true in the input decorator. So now Angular will kind of throw a fit if you don't provide it, so that way people can just know, right? It'll know like, hey, this is a required component and you did not provide it, bro, what are you doing?

You're trying to break your own app? Yes, I am, thank you. All right, okay, so now we have our input. That required part is optional, you don't have to put that, but it's a nice thing to do if you need it to render your application, okay? Now, we added our reference.

Okay, so now we got to use our listing component via the selector, that's right. So we're there, but guess what? As my son would say, ya-ta-ta, all right, it's like, what's happening here, that's how he draws attention to stuff, he goes, ya-ta-ta. All right, it's telling me it's required, which is helpful to me as a developer, because maybe I didn't write this component, maybe another team did.

Now I know what I need to provide, so I need to provide a car. But let's make sure we're going in order. Okay, we did our reference there, okay, and then we're gonna list, aha, so now I get to number four. So we did the first two parts, right?

We added to the imports, we already moved the template, now we have our input. And now it wants us to pass a reference car to the input. So this one sounds a little tricky, let's make sure we understand the parts. First thing we've gotta do is iterate. How do you iterate over something in a template?

>> For loop.
>> Yeah, for, a for loop. So we'll say, let car, maybe, of what list? Somebody yell it out for me.
>> carList.
>> carList, nice, thank you, I appreciate that. Then I gotta bring in my track. Did I get these cars with id? Nope, it's okay, we could track by car.

And then we'll just, okay, so now we're pretty close. Okay, let me stop right there. So now we have a for loop iterating over our carList. Fantastic, now, we gotta pass in a car. How do we send information in to our component?
>> An attribute.
>> Which one?

What's the name of it? What type is it called? It begins with an I and rhymes with send put.
>> Input?
>> Input, yeah, okay, there you go. All right, so the input here, it'll tell you, you see the first property there, I did a control space there.

And it's telling me this requires, so these are all things we could bind to if we wanted to, but you really need to bind to car, okay? And do we have a car to send it? We do. Now that can look a little tricky, if you read that, that looks a little tricky.

So let's just make a slight modification here. I would even go so far as to write carEntry instead, to make it more clear which is which, that makes it just more clear. So we get a car entry, which is what it is, from the collection carList, and then there's a property called car on the app listing component, the ListingComponent, and we're giving it a carEntry as the value there.

Now, if I take off these brackets, You see, it tells me, cuz remember I said without the brackets, it thinks everything's a string, and now we see. So here's where TypeScript comes into play. This is all TypeScript, this isn't Angular being Angular, this is TypeScript being TypeScript. TypeScript is telling me, you told me, this was your words, right, as a developer, you said that the input was of type car.

That's what you said, agree or disagree? Yeah, I said that. Okay, cool, then why are you giving me a string? You see, so TypeScript is just working in our favor. Okay, so I'm gonna switch it back to a property binding, which means the thing on the right-hand side now becomes an actual property, right?

It's like a value now, and it's the value from thing, okay, so we got that. So we're cooking right now, we're really cooking. So if we go back to, if we save everything, go back, our refresh page with too big font. Yeah, it's too big, I could probably fix this flex dial or something, we gotta fix that to a column or something that looks bad, we gotta do something.

Let's see if we can fix it. Oop, ain't no styles, ain't no styles when they're gone. I'm sorry, I paused, that's what I was singing. All right, let's see, can we change our style? [LAUGH] No styles there either. I think all the styles are global for this one, so that's why it's all.

We can work on the styles later, the styles are not important. All right, so now we got everything that we need, we got this part, so now we're gonna use output. Let's see, well, first, before we finish that, let's make sure that we got all of our listing component details.

Okay, we can do this quickly. So I'm back in listing, let me slow down for a second. Back in listing.component.ts, we're gonna fill in the details so that way we can tell that our car is actually being parsed in, okay? So we're gonna just take this and we're gonna do this quickly.

I'm not gonna talk too much through it. So we got a car.model, something like that, and then car.make, yeah, there we go, car.make. Okay, sounds good. All right, friends at home, I'm just filling in the properties, don't worry. You get car., what was that, year, okay, got it.

That's gonna be stuck in my head. Okay, great, thanks, Mark. We don't have transmission, we'll put something else here, we'll put anything else here. Let's put a price for now cuz I still wanna spend the time to fix that for now, all right. Wait, here, I know what we can do, we'll say that all are automatic, right?

You just do that, just take out that property binding and say they're all automatic, and then it's fine, it's fine. You get car.miles, okay, cool, and then car.price. Very fun, we're cooking, we are cooking with gas. All right, car.price, let's go. If I save this, I should have all my properties filled in in our listings.

And we're good, we're back to where we wanna be, right? We're good, we got the properties. And what's great about this is if we go to app.component.ts, look how clean that is. Look how clean that is. Wait, sorry, all the highlighting. Okay, you see the carEntry is a single car from our list.

Then we have a component that we say fill in the values with the provided variable that I give you. Fine, carEntry, and then we're good to go.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now