Check out a free preview of the full Angular 17+ Fundamentals course:
The "Component Composition" 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 the concept of component composition in Angular. They use the analogy of building with blocks to illustrate how components can be combined to create a full application. The instructor demonstrates how to import and reference a component in another component's template, and guides the students through creating a new component and updating the existing component to use it. They also address questions from the students about CSS selectors and component naming conventions.

Get Unlimited Access Now

Transcript from the "Component Composition" Lesson

[00:00:00]
>> So, remember we said this, a component is like this block, it's just the one piece. But with blocks, if you have kids, they're really painful to step on. I've stepped on a lot of toys. I have a small child right now. I've stepped on a lot of toys.

[00:00:15] A lot of toys have disappeared mysteriously from my house. Just letting you know. But when you take those blocks and put them together, you can build incredible things, right? So a single Lego block is one thing, but when you have a bunch of them together, you can do anything you put your mind to, really.

[00:00:30] And that's the same idea with components in Angular. You have that one component that we just saw for that product. But what if we could combine that with other components to build up a full application? How does that start to look? Well, the first step to making that happen is component composition, okay?

[00:00:46] Component composition, that's the first step to getting there. And how do we get to component composition? Here's our idea. We have our dashboard templates. So this is on top of dashboard. You say welcome back, you always wanna make your users feel welcome in your application. So what if I wanna use my UserInfo that has all the information about that person, but I have a component that maybe I wanna reuse other places, right?

[00:01:10] Or I wanna separate my stuff. Maybe somebody else is working on it and I'm working on a dashboard. How do we combine that work? What do we do? How do we make that happen? Okay, well, here's what it looks like in our component class. So in the dashboard, first thing we do is bring in the imports.

[00:01:29] It's the imports property. Okay, let me explain what's kinda happening here, because you might say, but, Mark, you already imported. There's an import right at the top. Remember I told you about that module thing that kinda manage the imports and what's available as a dependency. Well, when we took the modules away, we still needed a way to say, well, what other things does this component depend on to run, right?

[00:01:53] And so we have to right now, at this time, we have to do it manually through this imports array, where we say, okay, we file level import so that it's available to the file. And now how do we tell that the component, when the compiler gets involved, it knows that this is a dependency?

[00:02:10] So you add it to this imports array. Is this the most ergonomic version of this story? Not really, we're looking at ways to solve for this where you can just import at the top and just use in a template. Yeah, we know, other people do this, all right?

[00:02:24] We get it, I know. React does this, we get it. Okay, everybody relax, all right? [LAUGH] But for Angular, this is a relic of this other thing, right, where we had the module system and components need their dependencies defined this way. And so this is what we're doing for now, but we are working on a solution.

[00:02:41] So we imported the file, then you import it, and then you reference it. Remember that selector I was telling you about before? That's how you can talk about your component in a different place. So now the app info selector is from UserInfoComponent. Now, this is a little bit of a departure from other places.

[00:03:02] I use React the most, cuz a lot of people know React. In React, you use that class name or that function name, right, directly as your component. But here, we're using the selector, right, which is defined in your component. Cuz at the high level, this is just a way that Angular works when you wanna reference a different component in your template.

[00:03:26] You have to import it into the file, add it as a dependency to the component through the imports array, and then you use a selector for that component to reference it. Okay, I told you, I show you how we do it and then we go do it together.

[00:03:44] Now, this one, I'm gonna give you a few seconds to get started with this one. Few moments, I'm not gonna do seconds on you. All right, so let's do this. We're in 03-component-composition. Does anybody remember what's one of the first things we should do right now as we're switching activities?

[00:04:05]
>> Serve the new one.
>> Yeah, serve the new one. What did you say?
>> Okay.
>> No, I didn't-
>> I said look at the README.
>> That's definitely a part of it, yeah. But I just don't want people to get stuck, and then I wanna do this this and stop the other one.

[00:04:19]
>> It will stop the other one.
>> Yeah, that way we're not stuck on that part, okay? So let's do that. So, yeah, we should look at the README. We should be good developers and read the manuals, which I know developers do not love documentation. We don't do it.

[00:04:32] That's just a part of our story. I don't know why, it is just how we act, to our detriment. So let's read the documentation and know what's going on. So in the later activities as we get deeper, I leave you some context in case. So this is for you if you come back to this later and you just wanna go through the code itself, you can know the context of the example, and then you can also know what steps to take.

[00:04:55] So you don't have to read this now cuz we just talked about it. But if you came back to this later, you could just look through the examples itself, okay, and do this. We know how to run this example, so we can copy this code if we want.

[00:05:08] We can run it and then see what happens. I've tried not to give you broken code, so you can always at least run it. See, so this is what it starts off as, as our kinda dashboard. And we're gonna fill in this blank space with something. So let's go through the instructions.

[00:05:30] You can go ahead on your own and read them. I'm just gonna read them all out for our friends, all right? So we're going back to app.component.ts. So we're gonna update the component simply to refer to the UserInfoComponent, okay? Create this component with the following command. All right, so you gotta create a component.

[00:05:46] I gave you the command to run, you run this from the root of your project. You don't have to go into a separate, I mean, into the individual project. You just run it from the root of your project. Okay, then after you do that, Save your changes, and then we're gonna make sure we can run it, and then we're off to the races.

[00:06:07] Things are gonna be awesome. All right, so go ahead and get started with that. You gotta create the UserInfoComponent. So let's start doing this together now. So I'm going to 03-component-composition. I got my source. I go to app > app.component. And so there's a lot of code here.

[00:06:27] One of my ideas for this course was to give you some examples that felt a little bit more like something you'd actually encounter when you're working, so you just have a different experience, right? So for this one, we have this dashboard space, okay? That's this dashboard space. And so this first tile is where we're gonna put our work, okay?

[00:06:49] Whatever we do should go here. And I'm just gonna show you what I would do. And so you may have done this in your own work, like, okay, something goes here, just so I can make sure I'm in the right place. Anybody ever done it before when you're working on some new code?

[00:07:03] Okay, so now I'm in the right space, right? So that's the first tile, I know. Now, I just wanna put my user info component there. How do I create that? So let's see how to create that. So if we go to ng generate component, and I'll explain this command step by step.

[00:07:19] Let me just open up another thing. Let me explain this one step by step. Okay, I'm gonna explain it from here. That way you can see it. So first thing is ng, okay? So you've been typing ng a bit, friends. ng is from Angular, like ang. Somebody in the community, many moons ago, started calling it ng as a prefix and it stuck.

[00:07:42] And so now we're ng, right? Okay, so ng and then generate. So ng is for the Angular CLI, then generate is a command, it's a self command. The Angular CLI can do a lot of stuff. Can somebody tell me one other thing that Angular CLI can do?
>> Generate services.

[00:07:59]
>> Services, but what's one thing you did today, it's been doing?
>> It starts the server.
>> It starts the server, right? So ng server is one sub-command, generate is another one. And then as you hinted toward, right, now we're saying generate components, but it also generate services.

[00:08:16] It could also generate interfaces, also generate files. Can it generate tests? I'm not sure if it can generate tests or not. It might even be able to generate tests. The documentation has the full scope of what the CLI can do. But this is one of the things that makes Angular very interesting and compelling as a solution, is that this tooling is fully featured, okay, and very ergonomic driven for a developer experience.

[00:08:41] So we really wanna give you a nice experience. So then what's the name of the component we wanna generate? userinfo. Now, I have one other flag here. Again, this is going back to our multi-project workspace. So I gotta say, where should this go? If I generate it, where am I gonna put it?

[00:08:56] Okay, I wanna put it in this project. Okay, so we have that command, so let's just keep the party going. What happened to it? Okay, that's not me, that's VS Code acting weird. Okay, cuz I'm like, y'all, somebody put it in there. So ng generate, and then we'll tell you what it generates.

[00:09:15] Now, I've configured our projects today to be scaffolded in such a way it doesn't add a lot of that extra stuff. Don't be alarmed that if you ever do an Angular project on your own, not with our project setup, you'll get tests by default, you'll get a separate CSS by default, you'll get a separate HTML by default, and it also goes into its own file by default.

[00:09:37] So it does a lot for you, but for us, we don't need all that extra stuff. Good, so we generated it. Anybody remember the first thing we gotta do since we generated the component so we can use it? We gotta import it, that's right. We gotta import it cuz it's not a part of our file, it's called UserInfoComponent.

[00:09:59] That's the wrong one. All right, hold on. Let me just make sure I get the right one cuz now it's reading from everywhere. So there it is. You see, the name is UserinfoComponent. That's all right, sounds good. If I wanted that to be camel cased, I would have did user-info, right?

[00:10:18] And then it'll do a nice camel case for you. All right, so back, so we wanna get this component named as such. And now, if we try to ask for it, it should be able to find it from our local folder. Okay, good, from ./user-info. Okay, so that's the first step.

[00:10:32] Next step, let's go ahead and add our imports. I'm starting to as myself as a practice because sometimes my templates can start to grow a little bit of my component. I'm starting to do this. I do imports before the template, just so I can see it up front and I can just know, that's what I do, just a Mark thing, okay?

[00:10:52] So imports, and then [UserinfoComponent], make sure I put my comma in there. So now I'm ready to use it here. But it's gonna get nice, because the Angular Language Service is gonna help me. If I type. App, which is the prefix for our component, it'll show up there as one of my options.

[00:11:14] And, yes, I do wanna reference this component. Okay, we support self-closing tags for components as well, so this is something that you'll see. Sometimes you could write the full way, where you have open and close tags. But if you don't have anything to put in between, any children, you just do this, okay?

[00:11:30] So if we save it, userinfo works, which is the default message that you get. Now, if we wanted to, we can go in here and we can start. Now, we can flesh out our component and add more data if we wanted to. So a question from our community.

[00:11:44]
>> Where does the app-userinfo name come from?
>> Good question. Where does that name come from? So let's look at this. So I'm gonna dive into the actual component. All right, and then in my component metadata for the decorator, I have the selector, and whatever this is, is what is going to be in your application.

[00:12:07] So you can change this, you can update this to be whatever you want it to be. But watch out for name conflicts, because I don't know what will happen if you have components from two different name spaces with the same selector. I don't know what would happened, so just watch out.

[00:12:22] But that's why these prefixes are interesting. So this could be your company prefix. So let's say that I was still at American Express, right? I might do something like mx- or amx or something like that, you know what I mean, to know that it's a component from my team or whatever.

[00:12:38] Or maybe I'm on a different team, right? At Google, we have lots and lots of teams that use Angular. Thousands of applications at Google use Angular, okay, thousands. So we had different developers building component systems, so maybe a different team, right? Let's say I was on a team called, I don't know, fun team, you might do fun and then you know that's where that came from.

[00:12:58] So you got a lot of options here for this thing. Very good question. What other question can I answer?
>> Curious about the CSS, you're using the host pseudo selector.
>> Good question. Go ahead, continue.
>> I just haven't seen that before in the browser. The support isn't it great, so I'm curious why that was used.

[00:13:17]
>> Let's talk about that. Host pseudo selector, what is going on in my CSS? What does that mean? All right, good question. To answer that question, the best thing we can do is look at what is actually generated. Okay, let's look at what's actually generated. So if I go into the Chrome DevTools, I go all the way down, you can kinda tell that, okay, so here's my app-root.

[00:13:44] Let's see if I can find my application, because, here it is. You see where it says nghost and display: flex, from app component? So I'm saying whatever your container is going to be, because the app-root is not an HTML tag, that's an Angular, that's my app component container, right?

[00:14:02] Let's confirm. We don't have to guess, right? Where's my selector? You see, app-root. So an element is created for this component with that tag. How does that feel so far?
>> So it's not the data of CSS, it's an Angular hook attaching to that.
>> I see the question.

[00:14:23] I don't know the answer for sure about that. I don't know how we're linking it, whether it's the native functionality or Angular specific. Yeah, but with that app-root, guess what I'm able to do? So I find the element and then I can confirm that these are the styles.

[00:14:37] You the specificity, look at that. I haven't forgot about your question. It's still on my heart. You see that? All right, but now that's applying the style to this custom element here. Yeah, good question, I love that. Excellent question. All right, what other questions can I answer? Any questions in person and our friends here?

[00:15:00]
>> So go back to your, The app.component.ts-
>> Sure.
>> So article class title, so I put in app userinfo like that, I don't have the space, but what I'm getting in my browser is -1 and then shana@melissa.tv.
>> You know why? I could tell you why. If you look at the path from which you imported your userinfo, you probably imported the wrong one.

[00:15:42]
>> I see.
>> Yeah, that's from lesson 11.
>> Yeah., because it auto-filled this-
>> It did.
>> Rather long with trip.., okay, okay.
>> Yeah, so you want the one. So if this happens to you at home, so great, great point, if you try to import UserinfoComponent and then if something weird is happening, it's because it imported the one from lesson 11.

[00:16:02]
>> Yeah.
>> And so that happened to me, right, when I started this. I was like, wait, that feels weird.
>> Okay.
>> Yeah, so now it should be the right component. So you wanna make sure it's the one from ./userinfo/userinfo.component.
>> Okay.
>> Yeah, good stuff and make sure that spelling is right.

[00:16:18]
>> Yeah.
>> So lowercase i. All right, friends, let's get into it. So now we have our component setup and we have a nice little dashboard. And you could go and build your next SAS startup. Just make sure you include AI or something, so it can get $1 million evaluation right off the bet.

[00:16:35] All right, [LAUGH] that's a joke. Nobody do that, this is not ready for that, it's a joke. All right, so we've got our dashboard example. Before we move on, were there any other questions? What other questions were there, friends, that I can answer about this example? Sure.
>> What is standalone: true?

[00:16:53]
>> Mm-hm, so standalone: true. This is to let this be a component that doesn't require our module system in Angular. Angular has an optional module system that can organize your dependencies, and if you don't want to use that, you do standalone: true. And then you manage your own dependencies in the component with this import function.

[00:17:16] That's what the import function does then, yes.
>> Do component selectors need to be lowercase or kabab case, or is that just a convention?
>> I have never tried. Let's try it. Let's find out together. Let's see if we change this to be capital I, well, let's see if it selects it with capital I without us changing anything else.

[00:17:38] That's the first test. It does not select it anymore. You see, so it does not show up in our component. So now that means our end, we had an error, right? Ooh, that's too far, slow down. And then we also got an error, right? So the casing, that's what you're asking.

[00:17:56] The casing actually matters here. Excellent question, and I love that we get to experiment together to find out, okay? Now, do you need the hyphen there? I think it's what the kabab part means, yeah. I was like, Bob, who's Bob? Okay, so that still breaks down, but then we put it back together.

[00:18:16] And so you don't need any of that stuff. You get to customize your casing.