Component-Based Architecture in AngularJS 1.x and ES6 Using Services
This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Using Services" Lesson
>> Scott Moss: That's the whole point of services and factors and why we talk about them. Because we have those, we have that static data in our, what was it, the block controller. So we want to get rid of that and store that state somewhere else. So we shouldn't store state in our components for the same reason we should store state in our controllers.
[00:00:18] As before, you learned all this stuff yesterday. All right, so anybody know why do we don't wanna store state in our controllers? Yes?
>> Speaker 2: Kinda conflating concerns isn't it?
>> Scott Moss: Yeah it is, conflating concerns.
>> Speaker 3: Hard to test right?
>> Scott Moss: It is hard to test. Anything else?
>> Scott Moss: What if we wanna share that state with other controllers?
[00:00:43] Or, controllers are volatile they're bound to some template, which is probably balance and route somewhere and when you navigate away from that thing, the state goes with it. So it's gonna be erased or exit controller's gonna be re-initialized every time. So all your states gone. It's like you hit refresh on a browser when you navigate.
[00:01:00] You probably don't want that. You probably want that state to stay the same, because the thing you're navigating to is relying on it as well. So, putting state in something that's volatile, something that's meant to be destroyed and rebuilt. It's probably not a good idea. I can put this stuff in the database or I cannot.
[00:01:19] That's the difference, so putting aside our factory service, which is not bound to a view, which is great. It'll stay there until you hit refresh. So that's all, you want to put it there, and we can share it across multiple whoever wants it, whatever controller, whatever component wants it.
[00:01:36] So that's why Angular has services, just for that reason. So the location of the definition of the service is dependent on what components need it. And what I mean by that is if we go back and go over here. To go to the way our directory structure is.
[00:01:51] So if you were on step five, if you checkout step/five you'll see a new folder called shared, some stuff in here. So what I'm saying is the location of where the stuff is defined is dependant on what needs it, so if we code inside our components. And we're like okay we're gonna make this new factory this new service, but it's only gonna be for blog.
[00:02:11] Only blog needs this factor of service. So we create it in here, cuz that's the only thing that's gonna use it. So we can make another folder, or you can just put it right here on the root, however you wanna do it. But we definitely make it in this folder.
[00:02:22] All right, but let's say blog and home needed it. All right, so what we would do there is we're like, okay, we need to go up one directory to a common parent and create it there. So that's why I have shared. So sharing it would allow pretty much all components to be able to use whatever.
[00:02:41] Does that makes sense?
>> Scott Moss: Yeah, so there's more than one component that you need to register it at a common parent. I just chose the word share. Yes?
>> Speaker 2: So if you create a service-
>> Scott Moss: Mm-hm.
>> Speaker 2: And you create separate services for each controller, or you create a service that has multiple functions, that you can use.
[00:03:11] Is this different from just adding it as a service? I know it's confusing, but then dollar sign, I actually don't use dollar sign, but whatever you named your service and passing it to that controller, so that you can use methods that you show, like returning.
>> Scott Moss: Right.
>> Speaker 2: So, does that matter where it lives or does it matter where you use it?
>> Scott Moss: It definitely matters, well technically I guess it doesn't matter where it lives, because they're all gonna be registered eventually on the root module. So eventually they'll all be able to use it, but when it comes to testing it'll break because you put it in the wrong place.
[00:03:50] And then as far as like injecting it, yeah, it'll be the same thing, if you just have one service that you created it'll be the same state the same stuff. But if you made it each time for each component, it's gonna completely different, right? What's going to happen, especially if you give it the same name.
[00:04:04] The latest one to be registered would overwrite the previous ones.
>> Speaker 4: Question from on line Scott.
>> Scott Moss: Yes.
>> Speaker 4: Should services be stateless and factories be stateful? Or does it matter?
>> Scott Moss: I don't think it matters. There probably is a deeper meaning behind those two, but I don't think it really matters.
[00:04:26] I mean. A service is a constructor function. I mean if you want to store some state in there, you probably gonna have to, but I can see the argument of services not having that state in factories, having state. That's probably why they return different values. But deeper down a little more in depth than angular.
[00:04:45] They're all technically just called providers. So that's a little more advanced stuff, but all these are just call providers and the providers would make this stuff. So they really all just the same thing with a different syntax. So, but yeah, I can see the argument that might be a good way to figure out what you want to use.
[00:05:02] So, I would probably be for it, but I just don't use services at all. It's either factories or providers. That's it, I don't use anything else. Cool, any questions so far? Nope. Okay, so the big idea about services especially, with components. Is to hold our application state and define an API to interact with that state and expose it to a controller or another service again.
[00:05:31] I'm not talking about the service method, I'm talking about services in general. So we had the we had the state in the blogs the block controllers, now here's an example of like a to do factory or to do service that is actually keeping state. It is in charge of keeping the state which is here, which is defined here, all right?
[00:05:53] So we have this array of to do's and we have these methods that we create to interact with the state. And then we just expose those methods by returning them, and then on anything that injects this factory. Now can indirectly interact with the state by invoking these this API that we created.
[00:06:31] We only want you to interact with it the way we meant for you to interact with it, and that's by placing these methods on here. All right, so the only thing you can do is you can get one or you can get all or you can create one.
[00:06:42] That's it, you can't do anything else. You can't delete, you can't do none of that stuff. So if you got a reference to todos by returning all, then you're deleting your controller, then you'll just be deleting your reference, it's still gonna exist here. All right? So this is a good example, a very small example, too, of how you would actually keep state.
[00:07:01] So this is going to be here forever, until you refresh the browser, the state won't go anywhere. It doesn't matter how many routes you hit, what controller you're on or view you're on, it's gonna stay here. And if you use this same todos across multiple places in your application, it's still the same state.
[00:07:16] It doesn't reinitialize it every time. This todos array is still gonna stay here, nothing's gonna change. It's only gonna be initialized that first time and that's it. So it's like a cache really. Any questions on that?
>> Scott Moss: Okay, so what we'll do instead is, this is great. This is great, but this is like a inline factory as you can see, you literally just made like an anonymous function here In place of the line.
[00:07:48] So this is cool, but we're doing a component approach and we want everything to be broken out right? And we'd rather take advantage of ES2015 and use less of Angular when possible. So that's what we're gonna do. So we're gonna break this function out, and then build it somewhere else and register it with Angular later.
[00:08:06] Exactly like you did with the controllers. Exactly like you do with the directives. They were just functions and other files and then you imported them some at some point in time and told Angular about it. But if you start thinking about it really unlike controllers and directives where like they actually have to be registered with Angular to work.
[00:08:23] Like a directive just won't work, unless you tell Angular about it, but controller. I guess you might be able get it to work without Angular about it. But you still have to tell Angular about it. But with a factory service, if you think about it you really don't.
[00:08:36] You don't have to register with Angular, cuz it's just, I mean a factory is just a function that returns something and a service is a noble function. So with that being said, you don't really have to tell Angular, hey I'm gonna make a new service in a factory.
[00:09:23] I wouldn't do that. Although it would work the same. Does that make sense, the argument that I'm saying there?
>> Speaker 2: Still be treated as a singleton note?
>> Speaker 5: Cuz I thought angular container handles all that.
>> Scott Moss: Right. So if you're actually using the dot service method you would have to do some.
[00:09:37] You'd have to create your own signals and type thing because you have some issues there and yeah. The factory too, so you'd have to figure out how to do that. Whereas angular is like caching that, right? So yeah, you definitely have some problems. That's why I recommend don't doing it.
>> Scott Moss: Any questions on that? Yo.
>> Speaker 6: So you don't like to use services. But let's say you do want to use some single ten or something like that. Do you have a technique for doing that, or do you try to?
>> Scott Moss: Well if you use a factory. So if you just want to use a singleton.
[00:10:15] Which is, if you're a stantiated that singleton from some constructor function, which you probably are. Just instantiated inside of factory, and return that instance-
>> Speaker 6: And saving it for everyone. Okay.
>> Scott Moss: Correct. Then you're fine, yeah.