A singleton service in Angular
a way to share data and functionality easily across all modules or within a particular module of an angular application
Hi everyone, in this post, I will share my experience on how to create a singleton service in Angular using providedIn and providers arrays which is based on the principle of singleton design pattern.
What do you mean by singleton design pattern?
It's a creational design pattern that ensures that at any given point in time there exists only a single instance of a class and provides a way to access it globally.
What does singleton service mean with respect to angular?
A singleton service in angular is a service for which there exists only one instance in an application.
What are ways to create a singleton service in angular?
There are two ways to create a single service in angular that is by using -
- providedIn property
- NgModule providers arrays
What is the difference between providedIn property and NgModule providers arrays in angular and how it is used to create a singleton service in angular?
The main difference is the way a singleton service is created.
In the case of providedIn property, a singleton service is created by passing the providedIn property to the providedIn property, and with a default value of ‘root’ then the service will be available throughout the application as a singleton service.
Note: providedIn property is available only from angular 6.0 prior to that we have only providers array to register services in angular. Also there is a bundling impact, is that providedIn allows to tree-shake out Angular services that are not being used.
Below is the syntax of how to pass a providedIn property to a providedIn property.
@Injectable({ providedIn: ‘root’, })
Note: This property is handy if we want the service to be available as a singleton service across all modules and we do not have the requirement to restrict it to a particular feature module. Also providedIn property works irrespective of our service being eager loading or lazy loading module.
In the case of NgModule providers array, a singleton service is created by passing the service as a value to the providers array and if the NgModule is root app module then the service will be available throughout the application as a singleton service.
Below is the syntax of how to pass angular service to providers array.
@NgModule({
…
providers: [YourService],
…
})
Note: Providers array is handy if we do not want an application-wide singleton use and want to limit the scope of the singleton service to a particular module in the application. But in this case if NgModule is root module or eagerly loaded module than only the service will be available to the entire application.
Now that we have understood what is a singleton service and what are ways to create it, let's create a sample application.
Created an Authorization service as shown below in the screen -
Next added this Service to app module providers array as shown in the screen below -
Next created two more components that are Login and Home component as shown below in the screen:
Finally checked the browser URL to validate the instance. On clicking the login page in the browser we can see the service instance is called
Next, on clicking the login button, it goes to the home page and we still see that the same instance is used:
Note : In both login and home component same authorization service instance is getting used and is not called twice.
Also, the code snippet is written in the constructor of AuthorizationService as shown in the screen below strict the instance to load twice if another component mistakenly AuthorizationService provides in their component.
In order to prove this scenario let me update the login and home component with the same AuthorizationService in the providers array as shown below in the screen.
Next click on the browser as shown below on the screen to validate the issue.
Next let us validate one more scenario, what will happen if the constructor validation code is removed from AuthorizationService.
For this remove the code from the Authorization service as shown below on the screen.
Note: Even though providers array of the AppModule has AuthorizationService still it can violate singleton pattern as because of adding AuthorizationService to the providers array of login mad home component
In the below screen we can see this issue
Finally, let us validate a scenario by adding providedIn property in AuthorizationService as shown below in the screen.
And remove the providers array from AppModule as shown below in the screen.
Next again hit the browser and check and you can see that it working as expected
Note: Same holds for this case also if we add AuthorizationService to Providers array of login and home component than it will violet singleton pattern.
Hope this will help fellow developers who want to create a singleton service in angular
There are few more topics that I have not covered in this article those are eager loading and lazy loading module which you can deep dive into by going through it in angular official site.
I am just trying to share my experiences and am open to questions and constructive criticism that will help me to create more valuable resources for other developers.