This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Defining a Service" Lesson
>> Lukas Ruebbelke: So we've talked about components, we've talked about templates, now we're going to talk about services. Now before I get into services, let's just take a moment and talk about components. So components consist of what? A component class and an html template. A component class is that and metadata.
[00:00:24] So a component truly is an ES6 class with some metadata on top to tell Angular hey, this is a thing, I want you to know about it. So if we understand that and we understand the shape of ES6 classes and if we put a property on the class, it's available to the template, if we put a method on the class, it's available to the template.
[00:00:50] And that very basic shape of we have a class with properties and methods, making a transition to services is really easy.
>> Lukas Ruebbelke: A surprise! It's just a class. This to me is one of the biggest punch lines and it's a big ah-ha moment. When you are working with Angular 2 and above.
[00:01:19] Everything follows the same basic shape. So the footprint of Angular is now very, very small because it's just letting ES6 and tight script do all the work. So we've seen with our component, it's just a class with some metadata.
>> Lukas Ruebbelke: Service, if you can believe me, same exact thing, class, metadata.
[00:01:50] If we were doing a pipe, class, metadata. Directive, class, metadata and on and on and on. So we can reduce the majority of Angular to this simple basic shape, class, metadata. And more often than not the class has nothing to do with Angular, it's just the metadata that is telling you that this is how this is going to live in the application.
[00:02:23] So to that end, it's really quite simple. We define the service, we expose the service and we consume the service. So let's talk about defining a service. Now what we have here is class. Yay! And, so export class ItemsService, we have some methods, does some stuff. Fairly fine grain, you can imagine here that load, save, create, update, delete, we're kind of walking around crud.
[00:03:03] More so, this is where your rest API calls go. And some very fine grain specific methods, each one of them do one thing that now that we have a property on the class, it's now available for anything that is consuming it. But when it comes to defining a class, we are defining a service is just a class with this little bit of metadata right up here.
[00:03:39] And so technically, and I don't wanna get in to this, past culprit actually explained to me one time like, why you need it, and it has to do with how the metadata is generated and there's this one weird case where it will break. And so, I pretty much said whatever, it's the smallest piece of metadata that there is.
[00:03:59] And so, like, just put it on there. And it just ensures that the correct, that it's wired up correctly via the metadata. So class, properties, methods. You've created a class or service, which really looks quite a bit like a component.
>> Lukas Ruebbelke: From there. Well, we know how to register a component.
[00:04:25] We need to do the same thing with a service. The difference is that instead of going in the declarations, is it goes in providers. So you create the class, expose the class via the module, and then you can consume it. Would anybody like to take a guess of how you consume a service in a component?
>> Speaker 2: Pens the injection.
>> Lukas Ruebbelke: Pens the injection. Via?
>> Speaker 2: Construct.
>> Lukas Ruebbelke: Constructor's time.
>> Lukas Ruebbelke: So what's awesome about this, is I know at the morning when I was going over kind of these big picture things, it was like there's so much information. Even just for me to say it and articulate it, but as we start to expand it out.
[00:05:13] Things start to fall into place and you realize I'm just doing the same thing over and over. And so, this is how you provide a service to a component and/or another service that needs it. As a parameter and a constructor, and then using public or private. Generally it's private, that this under the hood does constructor assignment and makes it available for the rest of the class.
>> Speaker 3: Would you ever have more then one service in the constructor?
>> Lukas Ruebbelke: Yes.
>> Speaker 3: Okay.
>> Lukas Ruebbelke: So for instance, so what do you think that would look like? If one dependency is one parameter, two dependencies would be?
>> Speaker 3: Two parameters
>> Lukas Ruebbelke: Woo!
>> Lukas Ruebbelke: That's right, I'm gonna start bridge.
[00:06:21] If I was on master, I'm pulling in items in widgets like would literary look like here. In general, what I'll do at that point is I'll break it to a new line.
>> Speaker 3: Right.
>> Lukas Ruebbelke: And you just, you do it that way. So let me, I'm gonna deviate just for one second.
[00:07:07] Now try learning OP. But on that, it's really hard. And so, I had to actually go do Java, and then come back for me to actually wrap my mind around that. So what I wanna do real quick is just take a second to show what is happening with constructor assignment, cuz I don't wanna gloss over this.
[00:07:28] So I'm going to TypeScriptlenleng.org and if you go over here on the playground you can kind of start to, I think we'll give you somebody actually write some type script and then to generate it into ES5 for you. And so now, you'll notice that message is they're generating this on the ES5 is, nothing has happened to it.
[00:08:05] But let me just go like this.
>> Lukas Ruebbelke: And so, if I wanted this message parameter to exist outside of this. So let me just go test,
>> Lukas Ruebbelke: Let me just delete this. So now, I'm sending this in, if you remember, ES5 is scoped to function. So it's function block scope.
[00:08:34] The scope exists around the function. So once you put something into a function, then that is the lexical scope that it's assigned to. Cal Simpson has some amazing courses here. I recommend checking those out. He is definitely going to say this much better than I ever could. So we have this message property, we're sending in, and I want to reference it out here.
[00:09:00] So I wanna say, this.message = test.
>> Lukas Ruebbelke: Well, you can see here, it's saying, we can't do that, it doesn't exist. So in order for this to work, what I have to do is I have to go this.message = message.
>> Lukas Ruebbelke: But then, also what I have to do because it's TypeScript,
>> Lukas Ruebbelke: Like this. So if I was going to do this by hand, you can see in kind of this constructor this is saying message. The perimeter is assigned to a local member of it. And so, this is what is happening under the hood. So I can actually reference this, if I want to reference this thing outside of it or rather this value, I need to assign it to something that's local to that class.
[00:09:56] Now what I can do for shorthand is, check this out, when I go like this TypeScript under the hood is saying, because this is a private member we're going to go ahead and do this assignment automatically for you. And so, this is what is happening. And so, when we want to inject, let me do another one.
>> Lukas Ruebbelke: And let's go broadcast, cuz I have no idea why. But there's this string.
>> Lukas Ruebbelke: Same exact thing, framers coming in, it's assigning it to a local member. So that it can exist and we can reference it outside of the function. So this is why when we're doing Angular Dependency Injection, we are using this public or private modifier, this access modifier.
[00:11:00] Because under the hood,
>> Lukas Ruebbelke: I just copy this. Let's see if this works.
>> Lukas Ruebbelke: This is what's actually happening. But the minute I take this off it's just a parameter. The minute I put this on, it's a structure assignment. And so, if you are actually doing ES6 you would have to do this in the constructor, by hand.
[00:11:34] I love it when it's, you're gonna do this anyway, let's just do it for you. And that's exactly what's happening. So now, back to this.
>> Speaker 4: Is one of those a best practice like, is it better to do the private method or is it to kinda do the long end version?
>> Lukas Ruebbelke: So private is, in Angular, using constructor assignment is best practice, so that's public or private. It's considered best practice to use private, because rarely are you going to need to expose this as a public member for consumption somewhere else. I mean, there may be, I've seen it a few weird, odd times, especially with NTRX that you might expose a store or something or rather, the stores that you can broadcast from the template.
[00:12:33] But in my home component, I would never do, I would never say like, okay, this'll actually give us a good one. Click, itemService.load or something like that. Because what you're doing is you're breaking kind of the log demeter is that an object should only be able to go one degree to its child object or parent.
[00:13:08] So you don't actually wanna reach two degrees out of an object.
>> Speaker 4: Sure.
>> Lukas Ruebbelke: And so, this is why, also when you do it like this, you're now coupling this component to, or rather this template to this service. And so, this is why you make it private. It's cuz your component doesn't need to know or rather, the template doesn't need to know about the underlying implementation.
[00:13:33] So you wanna keep those nice and clean. So that's why it's considered best practice to one, use constructor assignment, because it's easier. It's actually easier even to read, because you just kinda know what's happening, once you understand it. But also, that it, you set it to private and it kind of implies that this is not going to be seen outside of this class.
[00:13:59] Now, the caveat to that is there is no concept of public and private in ES5. So this is only enforced at run time or rather, compile time. At run time, because it's ES5, all bets are off. And so, there's ways to kind of, if somebody really wanted to break it and really hit that private member, they could find a way to do it.
[00:14:19] But this is merely to communicate intent. And if I tried to access it while it's compiling it, I would be like, nope, don't do that.