1 00:00:06,540 --> 00:00:09,823 - In this section, we're going to define a service class, 2 00:00:09,823 --> 00:00:11,760 and in the following section 3 00:00:11,760 --> 00:00:13,500 we're going to see how to test it. 4 00:00:13,500 --> 00:00:16,800 So, in Angular, a service is a class that provides 5 00:00:16,800 --> 00:00:20,280 some functionality that other components are going to use. 6 00:00:20,280 --> 00:00:24,090 So, the idea is that your component has data 7 00:00:24,090 --> 00:00:27,540 and event handlers, but functionality 8 00:00:27,540 --> 00:00:30,030 you put into a service class instead, 9 00:00:30,030 --> 00:00:31,740 and then you can inject that service class 10 00:00:31,740 --> 00:00:33,000 anywhere it's needed. 11 00:00:33,000 --> 00:00:38,000 So, services are how you do dependency injection in Angular. 12 00:00:38,100 --> 00:00:39,810 So, this is how it works. 13 00:00:39,810 --> 00:00:43,170 You define a service class and then Angular 14 00:00:43,170 --> 00:00:45,570 will automatically create a singleton instance. 15 00:00:45,570 --> 00:00:48,000 By default, it creates a single instance 16 00:00:48,000 --> 00:00:49,470 of your service class. 17 00:00:49,470 --> 00:00:52,083 So, imagine I've defined a service class. 18 00:00:52,950 --> 00:00:55,500 Angular will create a single instance 19 00:00:55,500 --> 00:00:58,470 of my service class by default. 20 00:00:58,470 --> 00:01:01,350 It's called, it creates it at the root level, if you like, 21 00:01:01,350 --> 00:01:03,660 any component can can receive it. 22 00:01:03,660 --> 00:01:06,240 Any component that needs it, just declares it 23 00:01:06,240 --> 00:01:08,700 as a parameter in the constructor. 24 00:01:08,700 --> 00:01:11,700 So, if I have a component here, component one, 25 00:01:11,700 --> 00:01:14,790 in that constructor, I can declare a parameter 26 00:01:14,790 --> 00:01:16,350 of that service type. 27 00:01:16,350 --> 00:01:18,870 That service object will automatically be injected 28 00:01:18,870 --> 00:01:20,970 into the constructor for that component. 29 00:01:20,970 --> 00:01:23,442 Let's say I have another component that also 30 00:01:23,442 --> 00:01:27,060 declares the service as a constructive parameter, 31 00:01:27,060 --> 00:01:29,700 then it gets passed in there and so on. 32 00:01:29,700 --> 00:01:31,860 Okay, so whichever components needed, 33 00:01:31,860 --> 00:01:34,020 they will get injected by default. 34 00:01:34,020 --> 00:01:37,860 The same service object will be injected into each case. 35 00:01:37,860 --> 00:01:41,100 Now then, if you want to you can use Angular CLI 36 00:01:41,100 --> 00:01:43,080 to help you create services. 37 00:01:43,080 --> 00:01:43,913 Do this. 38 00:01:43,913 --> 00:01:47,808 Open up a command window in your Angular application folder. 39 00:01:47,808 --> 00:01:51,840 NG is the angular CLI, G for generate, 40 00:01:51,840 --> 00:01:54,390 create a service called product. 41 00:01:54,390 --> 00:01:56,490 You give it a lowercase name. 42 00:01:56,490 --> 00:01:59,490 It actually creates a class called product with a capital P. 43 00:01:59,490 --> 00:02:01,380 In fact, it generates two files. 44 00:02:01,380 --> 00:02:04,500 It'll generate the file in the source app folder. 45 00:02:04,500 --> 00:02:08,400 It'll generate a file called product.service.ts. 46 00:02:08,400 --> 00:02:11,730 The file names, tell you what the name of the service is, 47 00:02:11,730 --> 00:02:13,080 what type of thing it is. 48 00:02:13,080 --> 00:02:14,760 It's a service. 49 00:02:14,760 --> 00:02:17,010 It also generates a test file as well, 50 00:02:17,010 --> 00:02:19,140 so that you can write tests for your service. 51 00:02:19,140 --> 00:02:22,440 And, obviously, we're gonna do that coming up. 52 00:02:22,440 --> 00:02:24,660 I've already done this in the example application. 53 00:02:24,660 --> 00:02:27,930 So, if you're go into lesson 12, example three, 54 00:02:27,930 --> 00:02:30,960 it's basically, it's very similar to the product example 55 00:02:30,960 --> 00:02:34,260 from before, but now it has a service class involved. 56 00:02:34,260 --> 00:02:36,160 Let's open that up in the code window. 57 00:02:37,020 --> 00:02:40,500 So, here's my demo application for example three. 58 00:02:40,500 --> 00:02:42,570 If you go into the source app folder, 59 00:02:42,570 --> 00:02:46,470 you'll notice here is my product service. 60 00:02:46,470 --> 00:02:49,410 Now, I've actually written some real code in there. 61 00:02:49,410 --> 00:02:51,990 I'll talk about the code in a moment 62 00:02:51,990 --> 00:02:54,573 and there's the spec for it as well. 63 00:02:55,500 --> 00:02:58,410 Okay, so that's the service class that was generated 64 00:02:58,410 --> 00:03:00,557 and then I added code and that's the spec 65 00:03:00,557 --> 00:03:02,040 that was generated. 66 00:03:02,040 --> 00:03:04,233 Those are the two files generated for us. 67 00:03:05,160 --> 00:03:08,310 Okay, so what I thought we'd do is implement 68 00:03:08,310 --> 00:03:13,200 a proper service class, which gets product data. 69 00:03:13,200 --> 00:03:16,410 In reality, you probably get that data from a rest service. 70 00:03:16,410 --> 00:03:21,410 Okay, but in this example, I've got a product service class, 71 00:03:22,410 --> 00:03:24,780 with a method, get products. 72 00:03:24,780 --> 00:03:28,050 It returns an array of products, which are hard coded. 73 00:03:28,050 --> 00:03:29,850 And like I said, in reality, you'd probably have 74 00:03:29,850 --> 00:03:32,340 a rest service call here, you know, 75 00:03:32,340 --> 00:03:34,050 but the idea is the same. 76 00:03:34,050 --> 00:03:39,050 Now, the interesting thing here is the injectable decorator. 77 00:03:39,690 --> 00:03:41,220 When you define a service class, 78 00:03:41,220 --> 00:03:44,893 this was actually generated by Angular CLI, this part here. 79 00:03:44,893 --> 00:03:48,030 And what it says is that this product service class 80 00:03:48,030 --> 00:03:52,080 will automatically be created and made available 81 00:03:52,080 --> 00:03:53,520 at the root level. 82 00:03:53,520 --> 00:03:56,070 There's quite a lot of theory that we could get into here, 83 00:03:56,070 --> 00:03:59,320 but basically in a nutshell, what this means is 84 00:04:00,240 --> 00:04:04,260 when Angular starts up, Angular will create 85 00:04:04,260 --> 00:04:07,440 a single instance of this class 86 00:04:07,440 --> 00:04:09,420 and effectively it'll make it available 87 00:04:09,420 --> 00:04:11,255 in the root module level. 88 00:04:11,255 --> 00:04:16,255 Every service is provided or created by some level 89 00:04:17,400 --> 00:04:18,900 in your application. 90 00:04:18,900 --> 00:04:21,900 So, when you say provided in root, okay, 91 00:04:21,900 --> 00:04:25,080 what that really means is we have a module 92 00:04:25,080 --> 00:04:29,520 at the top level in the kind of, you know, 93 00:04:29,520 --> 00:04:32,130 the hierarchy of objects in our system. 94 00:04:32,130 --> 00:04:34,690 The module is pretty much the top level object 95 00:04:36,030 --> 00:04:40,860 in our system, and that module will basically be responsible 96 00:04:40,860 --> 00:04:45,860 for creating a singleton instance of this product service. 97 00:04:45,870 --> 00:04:47,223 I just call it PS. 98 00:04:48,060 --> 00:04:52,470 Okay, so the instance of my product service class 99 00:04:52,470 --> 00:04:55,230 will be provided in root level. 100 00:04:55,230 --> 00:04:57,252 And what that means is, there's kind of like a, 101 00:04:57,252 --> 00:04:59,760 almost like a object graph here. 102 00:04:59,760 --> 00:05:04,230 That model is responsible or basically owns 103 00:05:04,230 --> 00:05:06,540 the application component. 104 00:05:06,540 --> 00:05:10,380 And that also remember in my demo, I had a product 105 00:05:10,380 --> 00:05:12,780 component class as well. 106 00:05:12,780 --> 00:05:16,350 So, there was a definite hierarchy involved here. 107 00:05:16,350 --> 00:05:19,980 If you have a service provided at the root level, 108 00:05:19,980 --> 00:05:22,890 anything beneath it in the hierarchy 109 00:05:22,890 --> 00:05:26,130 can also use the same product service. 110 00:05:26,130 --> 00:05:29,760 In other words, if this component constructor says, 111 00:05:29,760 --> 00:05:33,450 I want to have a product service, it'll get this one, 112 00:05:33,450 --> 00:05:35,310 provided by its ancestor. 113 00:05:35,310 --> 00:05:37,830 Likewise, if product component said, 114 00:05:37,830 --> 00:05:40,080 I need to have a product service injected, 115 00:05:40,080 --> 00:05:42,990 it would also get the same instance 116 00:05:42,990 --> 00:05:46,080 injected there like that, okay? 117 00:05:46,080 --> 00:05:48,960 So, the fact it's provided in the root level 118 00:05:48,960 --> 00:05:52,590 means the module creates it and makes it available 119 00:05:52,590 --> 00:05:55,650 to all of the children underneath the module. 120 00:05:55,650 --> 00:05:59,700 There's a hierarchical injection mechanism going on. 121 00:05:59,700 --> 00:06:03,450 So, any constructor, so any component 122 00:06:03,450 --> 00:06:07,113 underneath module can have this service object injected. 123 00:06:07,950 --> 00:06:09,180 So, this is what you do. 124 00:06:09,180 --> 00:06:10,953 Here's my application component. 125 00:06:12,480 --> 00:06:17,100 It has an empty array, initially, of products. 126 00:06:17,100 --> 00:06:19,050 Have a look at the constructor. 127 00:06:19,050 --> 00:06:22,290 My constructor specifies the product service 128 00:06:22,290 --> 00:06:23,820 as a dependency. 129 00:06:23,820 --> 00:06:28,263 So, at this point, the picture that I drew just now, 130 00:06:29,370 --> 00:06:33,150 the root level in our application is the module. 131 00:06:33,150 --> 00:06:35,970 The module would've been responsible for creating 132 00:06:35,970 --> 00:06:39,540 the singleton instance of the product service class. 133 00:06:39,540 --> 00:06:41,896 And that instance will be injected 134 00:06:41,896 --> 00:06:46,080 into my application component. 135 00:06:46,080 --> 00:06:49,170 So, in my application component, I can call methods. 136 00:06:49,170 --> 00:06:51,060 I can invoke on my product service. 137 00:06:51,060 --> 00:06:52,560 I can say, get products. 138 00:06:52,560 --> 00:06:56,043 I can call the get products method on that service. 139 00:06:57,330 --> 00:07:00,870 In reality, that would probably talk to a rest service, 140 00:07:00,870 --> 00:07:03,180 like I said, but it doesn't really matter. 141 00:07:03,180 --> 00:07:06,272 The main thing is that my component manages 142 00:07:06,272 --> 00:07:08,610 kind of user interface effects, 143 00:07:08,610 --> 00:07:12,420 but anything functional is provided by the service layer, 144 00:07:12,420 --> 00:07:15,210 hence the name, it provides the service 145 00:07:15,210 --> 00:07:17,100 that our components can use. 146 00:07:17,100 --> 00:07:20,160 So, that's automatic, that Angular will automatically 147 00:07:20,160 --> 00:07:24,210 inject the service object into my constructor. 148 00:07:24,210 --> 00:07:27,150 So, I can then invoke methods upon it, like so. 149 00:07:27,150 --> 00:07:28,920 I just need to run the application. 150 00:07:28,920 --> 00:07:31,290 When you run the application Angular 151 00:07:31,290 --> 00:07:33,780 will create the service object. 152 00:07:33,780 --> 00:07:37,950 It'll pass the service object into my app component. 153 00:07:37,950 --> 00:07:40,890 An app component can say, get products, 154 00:07:40,890 --> 00:07:44,070 get us a bunch of products, passes those products down 155 00:07:44,070 --> 00:07:47,610 to its product components, and it displays them beautifully. 156 00:07:47,610 --> 00:07:50,700 So, generally this is definitely what you should do 157 00:07:50,700 --> 00:07:51,930 in your component. 158 00:07:51,930 --> 00:07:54,490 Your component basically stores data 159 00:07:55,590 --> 00:07:59,970 and has event handlers like that. 160 00:07:59,970 --> 00:08:03,690 Your HTML template will display the data 161 00:08:03,690 --> 00:08:06,240 and it will invoke event handlers, 162 00:08:06,240 --> 00:08:08,415 but the real functionality for your component 163 00:08:08,415 --> 00:08:10,770 is provided by services. 164 00:08:10,770 --> 00:08:14,621 And these services are injected into your component 165 00:08:14,621 --> 00:08:18,213 by the injection mechanism we've just discussed.