Check out a free preview of the full Building Awesome Web Apps with Angular 2 course:
The "Component Classes" Lesson is part of the full, Building Awesome Web Apps with Angular 2 course featured in this preview video. Here's what you'd learn in this lesson:

Lukas demonstrates his approach for creating component classes: Create, Import, Decorate, Enhance, and Repeat (CIDER).

Get Unlimited Access Now

Transcript from the "Component Classes" Lesson

[00:00:00]
>> Lukas Ruebbelke: In this module, we're gonna talk about the anatomy of a component, which we have already seen a bit. Then I'm going to talk about a mnemonic that I came up with. I just noticed I was doing the same thing over, and over, and over. And so I just came up with this mnemonic of CIDER, which is class, import, decorate, enhance, repeat.

[00:00:25] Class, import, decorate being kind of the three initial steps, then from there either you kind of enhance or you basically augment the behavior to taste, and then you repeat for subcomponents. And so we'll talk about how to enhance with properties and methods, enhanced with injectables, and than we'll talk about lifecycle hooks.

[00:00:47]
>> Lukas Ruebbelke: So the anatomy of a component, we've seen this, this graph is going to become our best friend. There's actually not a lot to see here. In a sense is I think that you really have a class, a template, metadata that kind of holds it together, and then you have event binding and property binding.

[00:01:09] And so when it comes to really, truly understanding a component in the broad sense is its five kind of main pieces.
>> Lukas Ruebbelke: Now let me just make a point here real quick, that just because we're using classes does not by default mean that we're using inheritance. So, coming from a more functional programming background, that when I saw like my goodness, JavaScript is getting these classical mechanisms baked into the spec.

[00:01:46] Like that does not bode well. Because now we're moving into kind of Java enterprise-y, where you're gonna basically be like, this class inherits from this class, inherits from this class, implements this interface and this interface, and [SOUND]. And so initially I was very resistant to the idea of just even a ES6 class.

[00:02:13] But then I realized that I don't necessarily have a problem with a class, especially as an organizational mechanism, I think it works really well. It's a really nice way to say, I have this thing that has methods and properties on it. I realize that what I really have a problem with is inheritance.

[00:02:34] I think inheritance is, on one hand, there's people that never use it, if you do, you're subhuman. There's some people that say well you can use one level inheritance. I think that generally when you're using inheritance, you can accomplish the same thing using composition. And so using dependency injection and these different things that allows you to extract out a piece of common behavior that you can then inject or compose it into multiple things.

[00:03:01] So this is an entirely separate subject, but the point is really avoid inheritance, use composition. But, because we're using classes, that doesn't mean, now I'm using inheritance, it's not. That it simply is, when you see it as an organizational mechanism, really kind of as an object with additional functionality, I think it makes it a lot easier to reconcile.

[00:03:36] So, we'll start with CIDER, first and foremost, class definition. So, at the core of every component is a class. So, we just create the component as an ES6 class. And then properties and methods on our component class are available for binding in the template. Export class ItemsComponent, step one, define the class.

[00:04:03] So every time I would do this, that's what I would start out with. From there, import, what is the bare minimum that this component needs to work? So first and foremost you are going to need to import component from Angular core. So import core Angular dependencies, import 3rd party dependencies, import your custom dependencies.

[00:04:33] So this approach also gives us a more fine grained control over managing what our application needs. As well as when you're testing it, then you can then stub these things out and replace them when you're setting up your test harness. So here, import { component } from '@angular/core', component import.

[00:04:57] From here, let's decorate our class. So now we are going to turn this into something that Angular 2 can use. So, we use the component syntax to decorate our class. And we can also decorate methods and properties within our class. We'll see this tomorrow for component driven architecture, but the most common is input and output.

[00:05:22] So just know that not only can you decorate the class, but can decorate properties and methods, which is super interesting. So now,
>> Lukas Ruebbelke: We've created the class.
>> Lukas Ruebbelke: We've imported our necessary dependencies and now we're going to decorate it using the @component metadata. And now we're telling Angular 2 that this class has a selector of app items, and it uses items.component.html as its template, and items.component.css for its styles.

[00:06:11]
>> Lukas Ruebbelke: And you can see here that as we add in methods and properties that within our template these are now available for us to bind to. So as we have items, as a member on our items component class, it's now available in the template.
>> Lukas Ruebbelke: Selected items same thing or for instance resetItem or selectedItem.

[00:06:37] These are now things that we can call using event binding.
>> Lukas Ruebbelke: So we can also decorate the class, so as to rather enhance the class with dependencies. And so we need to essentially inject or make the itemsService available for use within the class. So what we have here is within our constructor, we are setting itemService as a parameter, and then we can then use it in the rest of our class.

[00:07:16] Now I want to just call something out here. What we're looking at in our constructor is what's called constructor assignment. So you'll notice that there's actually nothing in the constructor. But within the ngOnInit, we are referencing the itemService as a local, basically property or method, member on the class.

[00:07:46] So how did this happen?
>> Lukas Ruebbelke: TypeScript by default is when you put an access modifier on a parameter, it assumes that that is then a method on, or rather a member on that class. And so what happens is, and this will get you at least once.
>> Lukas Ruebbelke: Let me just jump in to,

[00:08:19]
>> Lukas Ruebbelke: You know what, I will do this in,
>> Lukas Ruebbelke: StudentsComponent. And so this is not specific to anything we're going to do further along, but,
>> Lukas Ruebbelke: Now what I want to do is, private
>> Lukas Ruebbelke: And I can now reference this down here. But if we go down here and let's say I put in some parameter or let me do this this way.

[00:08:58] I'm creating a new method.
>> Lukas Ruebbelke: And I wanna pass in a student.
>> Lukas Ruebbelke: And then down here, I wanna delete a student. And when I want to reference this right here, this student parameter. Well, this would not work. If I want to, for instance, this.student, I would have no way to do that, because this parameter is scoped to the function that it's being passed into.

[00:09:36] So you can't reference a parameter outside of its function's scope. And so what happens is, without the access modifier, this is simply scoped to the function. And so, what you could do then, is this.studentsService
>> Lukas Ruebbelke: Equals,
>> Lukas Ruebbelke: Now what I'm doing is I'm essentially taking this and I'm assigning this to, sorry about that, to this parameter.

[00:10:14] And so now I'm saying take this parameter and I'm assigning it to a local member. Well TypeScript does this by default with an access modifier, or rather a constructor assignment. So adding the access modifier will then essentially take that and make it available for use within the rest of the application.

[00:10:39] So for instance, to follow this along, and you'll notice here even,
>> Lukas Ruebbelke: If I try to actually get type completion, it doesn't even know like where is it? If I go here,
>> Lukas Ruebbelke: Then it picks it right up. It knows, this is actually going to live outside of the constructor.

[00:11:00] And so for somebody from a classical background, I apologize. This may seem really like kind of review, like I've seen this, like I know this, but I've just seen this a lot from people coming from a JQuery with a ES5 background that are not familiar with constructors specifically.

[00:11:19] Is, they inject something into a constructor and it's not available to the rest of the class. And so, if you use ES6, then you need to manually say this dot whatever equals whatever the parameter is, or using TypeScript, it goes ahead and handles that for you. Does that make sense?

[00:11:48]
>> Speaker 2: There's a bit of discussion going on in the chat room about this, too, so.
>> Lukas Ruebbelke: Yes?
>> Speaker 2: About what the private is and also things like setters and getters and that sort of thing.
>> Lukas Ruebbelke: All right, let's do this. So this is just right for our own TypeScript.

[00:12:16] We'll go class,
>> Lukas Ruebbelke: So if we go like this, and myService.
>> Lukas Ruebbelke: You can see that it's scoped over here, to just a regular parameter, so it's just a function parameter. But,
>> Lukas Ruebbelke: The minute I go private.
>> Lukas Ruebbelke: Or public.
>> Lukas Ruebbelke: Then you can see over here, it's then now under the hood assigning it.

[00:12:59] It's saying, this.myService=myService, so that you can then use it outside of the constructor. So, the question is, could you do the same for non-constructor methods? And I'm thinking not, but we will see here.
>> Lukas Ruebbelke: So here.
>> Speaker 3: Hey Lucas?
>> Lukas Ruebbelke: Yes.
>> Speaker 3: Could you expand the type, the font?

[00:13:37]
>> Speaker 3: There you go.
>> Lukas Ruebbelke: Yeah, so if you can see here, this only works on the constructor. So I'm trying to do it here, and it's not taking. So a parameter property is only allowed in a constructor implementation.
>> Lukas Ruebbelke: Oops, now, what's important about this is,
>> Lukas Ruebbelke: You want to inject, in this case the studentsService via the constructor, but where you're really going to want to use it is in ngOnInit.

[00:14:17] And so this is where this comes in. And so, at least a very naive approach initially for me is, I would actually just reference studentsService right in the constructor. And then the minute I wanted to move it out of ngOnInit, then things fell apart.