When building any kind of application, it is often seen that a certain functionality is needed again and again at different points. It could be the functionality to display something in a certain way or retrieve data from a source, to name a few examples. Such a common case like this can appear in all kinds of development, be it front-end or back-end. A robust front-end development framework like Angular handles such a case by allowing the development of objects that can be imported by any part as needed. These objects can extract some common logic or data are known as services.

This article helps you understand what Angular services are and what are the different kinds of use-cases they can be used in. Angular services are not limited to one particular type of job and can contain methods that are repeatedly required by different components of the application. Afterward, this article will show what it is like to code service and what makes it accessible to any of the components.

The Gist Of What Angular Services Are

Given how fundamental components are to Angular applications, it is important to briefly go through them to further understand any other concept, like services. Apart from that, components and services are often confused with each other as well. Hence, it is necessary to refresh our understanding of components.

Components are the very backbone of Angular applications. All the different functionalities or visual elements of the application are attributed to a component. Every component contains the working logic for the functionality or visual element and the instructions for its visual rendering. Every Angular application is based on a tree of components. In the component tree, every component working is dependent on or consists of, other component(s).

For their working logic, components often need functions and methods that can get them data from a specific source or save that data. Such functions could come in handy for the other components as well. To make them accessible to all components, they are coded into objects called services. These services, or other classes, become the dependency of the components that require them. The main aim of services is to make them modular, testable, and reusable. Services are also used as communication channels between components, as they are accessible to all.

Notice that the main difference between components and services comes in the fact that the latter does not do anything related to the UI. Along with that, As a rule of thumb, it is often advised that all the working logic of the application should be implemented as services. Aspects that involve the UI in any way, such as taking user input, should be made through components. Angular itself offers built-in services that can be used, such as the HTTP service to send data requests.

Creating And Using Angular Services

As discussed above, service becomes a component’s dependency if the component is utilizing the service. Angular provides a system through which a component requests the provision of a service through a provider, rather than creating it, at instantiation. Such a design pattern is called dependency injection. However, there can also be services not injectable and can be directly imported wherever needed. The service itself is created in a way given in the following example.

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

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

The @Injectable decorator specifies the following class as something that can be injected. The providedIn attribute is given a value of 'root', which means it is accessible for all. If a certain component is to use a service, it needs to include it and its return type in the constructor.

constructor(private service: ExampleService) { }

In particular, the component would be specifying its dependency on the service as in the above example and using the service like in the following one.

@Component({
	selector: 'dashboard',
	templateUrl: './dashboard.component.html',
	styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
	variables: string;
	constructor(private service: ExampleService) {
		this.variables = service.get();
}

A service can have another service as a dependency. That particular case is handle in the exact same way. That is, the service class’ constructor has the other service as a parameter.

Some important tips regarding using the dependency injection system and services are as follows:

  1. Keep your service focused on one application. Trying to make a do-it-all service that can juggle all kinds of functionalities will become hard to maintain and eventually test.

  2. The service ought to be justified. If the service is hardly used more than once throughout the application, maybe it needs to be reconsidered. This would unnecessarily increase the load on the dependency injection system and the overall complexity.

  3. The design of the services should be consistent. If multiple services have a similar working, they should be coded similarly as well, such as similar names and design of methods.

Testing Angular Services The Right Way

As services are going to contain most of the application logic, the unit testing of Angular applications must also focus on ensuring they are working as intended. Services can be tested by injecting them into the testing classes being used and checking for valid outcomes, such as the right data being fetched. In addition to that, the providers of the service need to be checked as well. Angular’s TestBed part of its testing utilities can be used to create a test module that is injected with the particular service being tested. Apart from that, Angular also provides a dedicated HttpClientTestingModule that can be used to particularly test the HTTP class by a service.

Services also come to play in the testing of a component, if it is its dependency. The testing of such a component can be done either so that it involves using the service or that it uses a fake service. The latter part can give better access to the workings of a component and the values it is receiving through the API via a service.

Conclusion

As you saw in this article, services are the second foundational element of an Angular application after components. A fine balance between both of them, with each given the dedicated responsibilities, can result in a most smooth Angular application. Creating services to handle all of the application logic will help create a more modular application that encourages code reusability throughout. This article discussed how a service is made accessible on different hierarchical levels. It also gave tips on coding the most efficient services along with giving exact syntax. It also showed what the testing process of services looks like and how it can be used to better test components.

Комментарии (0)