Angular Services

Angular services are a very important building block in angular, they can help us to centralize general tasks, share data, prevent code duplication and to communicate between components.

What is an Angular Service?

  • Angular service is a reusable piece of functionality that can be shared across components.
  • Angular service should be responsible for a single piece of functionality
  • Angular service are able to be delivered when and where they needed.

According to angular style guide, we should “limit the logic in a component to only that required for the view. All other logic should be delegated to services“.

The code in the component should :

  • Control and manipulate the user interface.
  • Call services to provide functionality not directly related to the user interface.

We should use a service when:

  • The necessary functionality is not required by the view
  • You need to share logic or business rules across components
  • you need to share data across components

Creating a Service

service is a typescript class that can have public and private methods, properties, and constructor. we can recognize them as a service by the @Injectable decorator above the class definition. The @Injectable decorator is not required if the service is not having other services injected into it, but it is considered a best practice to add the @Injectable decorator anyway.

Before service can be injected to a component, an instance of it must be provided to the angular’s dependency injection system. It provided with something known as a provider. after that the injector can make the service available to the components that want to use it.

once the injector delivered an instance of the service, it will cache it and deliver the same instance when ever future request are made for that service. because an injector only keep a single instance of each service, services are singleton.


import { Injectable } from '@angular/core';

@Injectable()
export class MyService {}


<!-- app.module.ts -->
import { MyService} from 'path/to/my-service.service';

@NgModule({
  ...
  providers: [MyService],
  ...
})
export class AppModule {}

In angular 6 and above we can provide application-wide services in a different way. instead of adding a service class to the providers[] array in AppModule, you can set the following config in @Injectable():


import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class MyService {}

Notice that there is no need to add the service to the providers array in AppModule when using the “providedIn: ‘root’” and it give us an advantage, it means that the service can be loaded lazily by angular and redundant code can be removed automatically. this can lead to better performance and loading speed.

Using a Service

Providers are like a blueprint for how a service should be created. they providing the new instance by using the new keyword to instantiate a new instance of the service class. then the new service is handed over to one of angular dependency injectors. the injector maintains a single instance of each service it’s responsible for delivering to components that request them. components request a services being injected into them using a technique known as “constructor injection”.


export class MyComponent{
  constructor(private dataService: DataService) {
    this.data = this.dataService.getData();
 }
}

In the above code I inject a service of type DataService, the dependency injection system will see that I want a DataService instance. the injector will use the provider blueprint for that type to create one if it doesn’t already have one cached and then deliver it to the constructor parameter in the component.