![]()
In AngularJS, singleton services are reusable components that provide shared logic and state across an application. They are instantiated once and used wherever needed.
Why Use Singleton Services?
Data Sharing โ Share data across multiple controllers.
Code Reusability โ Encapsulate business logic in one place.
Performance Improvement โ Prevent redundant object creation.
Dependency Injection โ Easily manage dependencies.
1. Creating a Singleton Service in AngularJS
A singleton service is instantiated once and remains the same throughout the application lifecycle.
Using .service()
var app = angular.module("myApp", []);
// Singleton Service
app.service("UserService", function () {
this.user = { name: "John Doe", email: "john@example.com" };
this.getUser = function () {
return this.user;
};
this.setUser = function (userData) {
this.user = userData;
};
});
// Controller using the service
app.controller("UserController", function ($scope, UserService) {
$scope.user = UserService.getUser();
$scope.updateUser = function () {
UserService.setUser({ name: "Jane Doe", email: "jane@example.com" });
$scope.user = UserService.getUser();
};
});
๐น How it Works:
UserServiceis a singleton that holds user data.getUser()retrieves the shared data.setUser()updates the shared state across the app.
2. Creating a Singleton with Factory
A factory returns an object, making it more flexible than a service.
app.factory("UserFactory", function () {
var user = { name: "John Doe", email: "john@example.com" };
return {
getUser: function () {
return user;
},
setUser: function (userData) {
user = userData;
}
};
});
Key Differences from .service()
- Factory returns an object explicitly instead of using
this. - Useful for adding private variables and complex logic before returning an object.
3. Making an API-Driven Singleton Service
Often, services fetch data from an API and provide it throughout the app.
app.service("UserService", function ($http) {
var user = null;
this.getUser = function () {
if (!user) {
return $http.get("https://jsonplaceholder.typicode.com/users/1").then(function (response) {
user = response.data;
return user;
});
}
return Promise.resolve(user);
};
});
๐น Benefits
- Data is fetched only once.
Promise.resolve(user)prevents redundant API calls.
4. Using a Provider for Configurable Singleton Services
If a service needs configuration before being used, a provider is ideal.
app.provider("ConfigService", function () {
var apiUrl = "https://default-api.com";
this.setApiUrl = function (url) {
apiUrl = url;
};
this.$get = function () {
return {
getApiUrl: function () {
return apiUrl;
}
};
};
});
// Configure the service before the app runs
app.config(function (ConfigServiceProvider) {
ConfigServiceProvider.setApiUrl("https://jsonplaceholder.typicode.com");
});
app.controller("ConfigController", function ($scope, ConfigService) {
$scope.apiUrl = ConfigService.getApiUrl();
});
๐น Use Case:
- Configure an API base URL dynamically before the app loads.
5. Choosing the Right Singleton Approach
| Method | Best For |
|---|---|
.service() | Simple objects with methods |
.factory() | More flexibility & complex logic |
.provider() | Services requiring configuration |
