- In this section, we're going to define a service class,
and in the following section
we're going to see how to test it.
So, in Angular, a service is a class that provides
some functionality that other components are going to use.
So, the idea is that your component has data
and event handlers, but functionality
you put into a service class instead,
and then you can inject that service class
anywhere it's needed.
So, services are how you do dependency injection in Angular.
So, this is how it works.
You define a service class and then Angular
will automatically create a singleton instance.
By default, it creates a single instance
of your service class.
So, imagine I've defined a service class.
Angular will create a single instance
of my service class by default.
It's called, it creates it at the root level, if you like,
any component can can receive it.
Any component that needs it, just declares it
as a parameter in the constructor.
So, if I have a component here, component one,
in that constructor, I can declare a parameter
of that service type.
That service object will automatically be injected
into the constructor for that component.
Let's say I have another component that also
declares the service as a constructive parameter,
then it gets passed in there and so on.
Okay, so whichever components needed,
they will get injected by default.
The same service object will be injected into each case.
Now then, if you want to you can use Angular CLI
to help you create services.
Do this.
Open up a command window in your Angular application folder.
NG is the angular CLI, G for generate,
create a service called product.
You give it a lowercase name.
It actually creates a class called product with a capital P.
In fact, it generates two files.
It'll generate the file in the source app folder.
It'll generate a file called product.service.ts.
The file names, tell you what the name of the service is,
what type of thing it is.
It's a service.
It also generates a test file as well,
so that you can write tests for your service.
And, obviously, we're gonna do that coming up.
I've already done this in the example application.
So, if you're go into lesson 12, example three,
it's basically, it's very similar to the product example
from before, but now it has a service class involved.
Let's open that up in the code window.
So, here's my demo application for example three.
If you go into the source app folder,
you'll notice here is my product service.
Now, I've actually written some real code in there.
I'll talk about the code in a moment
and there's the spec for it as well.
Okay, so that's the service class that was generated
and then I added code and that's the spec
that was generated.
Those are the two files generated for us.
Okay, so what I thought we'd do is implement
a proper service class, which gets product data.
In reality, you probably get that data from a rest service.
Okay, but in this example, I've got a product service class,
with a method, get products.
It returns an array of products, which are hard coded.
And like I said, in reality, you'd probably have
a rest service call here, you know,
but the idea is the same.
Now, the interesting thing here is the injectable decorator.
When you define a service class,
this was actually generated by Angular CLI, this part here.
And what it says is that this product service class
will automatically be created and made available
at the root level.
There's quite a lot of theory that we could get into here,
but basically in a nutshell, what this means is
when Angular starts up, Angular will create
a single instance of this class
and effectively it'll make it available
in the root module level.
Every service is provided or created by some level
in your application.
So, when you say provided in root, okay,
what that really means is we have a module
at the top level in the kind of, you know,
the hierarchy of objects in our system.
The module is pretty much the top level object
in our system, and that module will basically be responsible
for creating a singleton instance of this product service.
I just call it PS.
Okay, so the instance of my product service class
will be provided in root level.
And what that means is, there's kind of like a,
almost like a object graph here.
That model is responsible or basically owns
the application component.
And that also remember in my demo, I had a product
component class as well.
So, there was a definite hierarchy involved here.
If you have a service provided at the root level,
anything beneath it in the hierarchy
can also use the same product service.
In other words, if this component constructor says,
I want to have a product service, it'll get this one,
provided by its ancestor.
Likewise, if product component said,
I need to have a product service injected,
it would also get the same instance
injected there like that, okay?
So, the fact it's provided in the root level
means the module creates it and makes it available
to all of the children underneath the module.
There's a hierarchical injection mechanism going on.
So, any constructor, so any component
underneath module can have this service object injected.
So, this is what you do.
Here's my application component.
It has an empty array, initially, of products.
Have a look at the constructor.
My constructor specifies the product service
as a dependency.
So, at this point, the picture that I drew just now,
the root level in our application is the module.
The module would've been responsible for creating
the singleton instance of the product service class.
And that instance will be injected
into my application component.
So, in my application component, I can call methods.
I can invoke on my product service.
I can say, get products.
I can call the get products method on that service.
In reality, that would probably talk to a rest service,
like I said, but it doesn't really matter.
The main thing is that my component manages
kind of user interface effects,
but anything functional is provided by the service layer,
hence the name, it provides the service
that our components can use.
So, that's automatic, that Angular will automatically
inject the service object into my constructor.
So, I can then invoke methods upon it, like so.
I just need to run the application.
When you run the application Angular
will create the service object.
It'll pass the service object into my app component.
An app component can say, get products,
get us a bunch of products, passes those products down
to its product components, and it displays them beautifully.
So, generally this is definitely what you should do
in your component.
Your component basically stores data
and has event handlers like that.
Your HTML template will display the data
and it will invoke event handlers,
but the real functionality for your component
is provided by services.
And these services are injected into your component
by the injection mechanism we've just discussed.