# Services in Angular

A service is anything that an application needs to complete a certain task or to carry out an operation. It can be any value, a function or a feature that the app needs. A service class is just another TypeScript class but it has very defined and narrow function. It is created with the sole purpose of doing something very specific and doing it well.

Components delegate tasks to services so they can stay lean. These tasks can be anything from logging a simple message to the console to uploading files to a web server. All the components do is use the service and the service takes care of everything. The components do not have the code to do the complicated tasks and thus can focus on what they are intended to do, interacting with the user.

Angular distinguishes components from services to increase modularity and reusability. A component can delegate certain tasks to services, such as fetching data from the server, validating user input, or logging directly to the console. By defining such processing tasks in an injectable service class, you make those tasks available to any component. You can also make your app more adaptable by injecting different providers of the same kind of service, as appropriate in different circumstances.

Angular doesn't enforce these principles. Angular does help you follow these principles by making it easy to factor your application logic into services and make those services available to components through dependency injection.

### Dependency Injection

As an application grows and becomes large, it is required that we do not program the same code entity over and over again. Instead, it is advised to use the code-entity, wherever possible, within the application to increase code reusability. These code-entities are called as dependencies as the components may depend on these to complete their tasks. The process of providing these code-entities to the dependent client is called dependency injection. It also entails the participation of another code entity which is called the injector. The injector will take responsibility for instantiating and bootstrapping the required dependencies so they are ready for use from the very moment they are successfully injected in the client.

This is very important since the client knows nothing about how to instantiate its own dependencies and it only knows how to use the interface they implement in order to use them.

Angular has a very sophisticated Dependency-injection system that eases the process of exposing required dependencies to any entity that might exist in an Angular application, regardless of whether it is a component, a directive, a pipe, or any other custom service or provider object.

Now that we know what is dependency injection in Angular, let’s create a service and see how we can actually implement DI in an Angular application.

### Creating a Service

We can, as always, use the amazing Angular CLI to create a new service in an Angular app. All we have to do is type in the following command in the terminal (while in the project directory) to create a new service.

ng generate service <service-name>

Let’s create a service called Time. The above command would become,

ng generate service Time

This command generates a few files and folders in the project and also it updates a few files.

As you can see, it created two new files -time.service.spec.ts and time.service.ts. You guessed it right, the *.spec.ts file is for Unit testing the service, so if you want to, go ahead and delete it for now. However, if you do not want the testing files to be generated at all, you can use the --skipTests=true|false flag in the command to allow/disallow that. So the following command would only generate the time.service.ts file.

ng generate service Time --skipTests=true

Next, we need to add this service to the app.module.ts file’s NgModule. So let’s do that. All you have to do is add the TimeService class to the providers array. You will also have to import the TimeService class up top.

Here is how the modified app.module.ts file looks like.

At this point, the service or provider TimeService is part of our project but it is not being used anywhere. However, if you open the time.service.ts file and look at it, you should be able to notice a new decorator in this file - @Injectable. This decorator marks this TypeScript class as a class that can only be instantiated once and will be injected to other entities in the project.

Once you create a new service and add it to the Module, stop the development service and start it again, otherwise the service may not work.

### Using a Service

To be able to use it anywhere in the project, we will have to write some function inside the service that we can then use from another component. Add the following code to your service file - time.service.ts.

I have added a new method called getTime() in the TimeService class that just returns the current time. Now that we have a working service, let’s use it in our only component - the AppComponent.

Since AppComponent and TimeService are part of the same module, we can directly inject the service in the Component class. To do that, you have to pass it as in argument, to the constructor of the Component class as shown below.

You will have to import the TimeService class from the time.service.ts file as well on the top if it is not added automatically.

import { TimeService } from './time.service';

We are now all set. Simple and quick. Let’s use the service’s method now - the getTime() method. Afterall, that’s why we created the service in the first place. To use the method, all you have to do is use the instance timeService of the service that we have created while injecting the service. Let’s display the time returned by the service on the page.

Define two properties currentDate: String and currentTime: String in the AppComponent class. These will be used for interpolation.

Next, inside the constructor, add the following code.

this.currentDate = this.timeService.getTime().toLocaleDateString();
this.currentTime = this.timeService.getTime().toLocaleTimeString();

In the above code, we are using timeService (which is an instance of the TimeService service) and once we get the JavaScript Date, we extract the Date and Time Strings and assign them to currentDate and currentTime respectively. As this point, you can log both these strings to the console and see if you get proper values of date and time.

Finally, let’s display these value on the page using interpolation or property binding. In you app.component.html, add the following code.

<div>
<div>Current Date: {{ currentDate }}</div>
<div>Current TIme {{ currentTime }}</div>
</div>

Save the file and have a look at it in the browser. You should be able to see the current date and time in the browser.

And that’s how you can create and use a Service in Angular. All you have to do is inject the service in the components and then use it throughout our component. You can use it in all your components.

Since services are instantiated only once, a single instance of a service is shared across all components and entities using the service. This means that the service data is also shared across all components. Services are therefore singletons. We can also use services to share information between components as well. Let’s have a look at how we can do that.

### Using a Service for Data Sharing

An Angular application can have a number or components. As the app grows, the components also grow in size and number. It is a good practice also to keep the components small and build new components out of bigger ones but as the number of components grow, there appears a need to share data between these components.

We have already seen in a previous module how data sharing can be done between two components using @Input decorator if they are related with parent-child relationship or using @Output decorator for vice-versa. However, it gets complicated if the two components in the app that need data sharing are not related at all. In such cases, we use Angular Services to share data between components.

Since services are singletons, they can be instantiated just once throughout the lifecycle of the app. Data is once set in a service object from somewhere in the app, and then can be accessed from anywhere else in the app, thus enabling data sharing.

Let’s build two components quickly an enable data sharing between these components. Let’s call these components Component A and Component B. Then we will create a service called DataService to share data between these components.

Create Component A using the Angular CLI and then add an input field and a button in the component’s template. This will be used to set the value of some data in the service.

ng g c Component A

The command generates a new folder for Component A with all the required files. Open up the file component-a.component.html and add a form with an input element and a button. The code will look something like this.

We have bound the value of the text in the input HTML element to a variable called name using NgModel directive. We have also bound the click event of the button to a method setName(). Next, let’s create this property and method in the TypeScript class.

As of now, we are simply logging the value of name in the setName() method. We will come back to this method after creating the service. Finally, let’s put in the ComponentA, using its selector app-component-a, in the AppComponent. Open app.component.html and put in the new component there.

We are half done. Let’s repeat the exercise for Component B as well but instead of creating the method setName(), this time we create one with the name getName().

Finally, we place Component B in the app.component.html as well.

At this point, let’s save everything and see how the app looks like.

Perfect!

Finally, it is time to create the service and get everything working. Let’s create a service called DataService. The service will have one property called name and two methods inside of it, namely, setName() and getName().

ng generate service Data --skipTests=true

This creates a file called data.service.ts. Before we open the file and start writing the code, let’s add the DataService class to the providers array in the AppModule (app.module.ts).

Next, add the methods and the property to the service class as shown below.

Now that the service is all set, let’s go back to ComponentA’s TS class and update the code in the setName() method.

1. Import the DataService service.
2. Instantiate the service by injecting it into the constructor of the class.
3. Use the service in the setName() method and pass the value of the name.

Similarly, let’s get to the TypeScript class in ComponentB and update the getName() methods to use the DataService.

Save everything and let’s test it out.

The value is set in the service when you click the Submit button in ComponentA. You retrieve the same value in ComponentB when you click on the Retrieve button in ComponentB. Awesome, right?

That’s all for Services in Angular.

## Node JS Tutorial

Build various types of web applications,command-line application,etc.
7587
Node JS Tutorial

Build various types of web applications,command-line application,etc....