In AngularJS, a service is a reusable component that encapsulates logic, shares data, and handles API interactions. Custom services allow developers to organize code efficiently, reduce duplication, and enhance maintainability.
This guide will explain how to create custom services in AngularJS, covering different approaches and best practices.
1. Why Use Custom Services in AngularJS?
Custom services help in:
Code Reusability – Write logic once and use it across multiple controllers and components.
Separation of Concerns – Keep controllers focused on UI logic while services handle business logic.
Dependency Injection – Services can be easily injected into other components, improving testability.
Data Sharing – Services can maintain a state that is shared across different controllers.
2. Different Ways to Create Custom Services
AngularJS provides three main methods for creating custom services:
- Factory (
.factory()) – Returns an object with properties and functions. - Service (
.service()) – Uses a constructor function withthisto define properties and methods. - Provider (
.provider()) – Used when we need to configure a service before runtime.
Let’s explore each method with examples.
3. Creating a Custom Service Using .factory()
The factory pattern returns an object containing methods that provide specific functionality.
Example – Creating a User Service Using Factory
var app = angular.module('myApp', []);
app.factory('UserService', function() {
var user = { name: "John Doe", age: 25 };
return {
getUser: function() {
return user;
},
setUser: function(newUser) {
user = newUser;
}
};
});
app.controller('UserController', function(UserService) {
var vm = this;
vm.userData = UserService.getUser();
});
<div ng-controller="UserController as userCtrl">
<h1>{{ userCtrl.userData.name }}</h1>
<p>Age: {{ userCtrl.userData.age }}</p>
</div>
Why Use .factory()?
- Best when dealing with object-based logic.
- Encapsulates logic in a function and returns an object.
4. Creating a Custom Service Using .service()
The .service() method is used when creating an object using a constructor function.
Example – Creating a User Service Using Service
app.service('UserService', function() {
this.name = "John Doe";
this.age = 25;
this.getUser = function() {
return { name: this.name, age: this.age };
};
this.setUser = function(name, age) {
this.name = name;
this.age = age;
};
});
app.controller('UserController', function(UserService) {
var vm = this;
vm.userData = UserService.getUser();
});
Why Use .service()?
- Useful for object-oriented patterns.
- Uses
thisfor property and method definitions.
5. Creating a Custom Service Using .provider()
The .provider() method is the most configurable service type. It allows setting values before application runs.
Example – Creating a Configurable Service Using .provider()
app.provider('UserService', function() {
var userName = "Default User";
this.setUserName = function(name) {
userName = name;
};
this.$get = function() {
return {
getUserName: function() {
return userName;
}
};
};
});
// Configuring the service before app starts
app.config(function(UserServiceProvider) {
UserServiceProvider.setUserName("Configured User");
});
app.controller('UserController', function(UserService) {
var vm = this;
vm.username = UserService.getUserName();
});
Why Use .provider()?
- Best for configurable services where values need to be set at runtime.
6. Example – Custom Service for Fetching Data Using $http
The $http service is commonly used for fetching data from APIs.
Example – Fetching User Data from an API
app.factory('UserService', function($http) {
return {
getUsers: function() {
return $http.get('https://jsonplaceholder.typicode.com/users');
}
};
});
app.controller('UserController', function(UserService) {
var vm = this;
UserService.getUsers().then(function(response) {
vm.users = response.data;
});
});
<div ng-controller="UserController as userCtrl">
<ul>
<li ng-repeat="user in userCtrl.users">
{{ user.name }} - {{ user.email }}
</li>
</ul>
</div>
Why Use $http in a Service?
- Simplifies API calls by keeping them outside the controller.
7. Sharing Data Between Controllers Using a Service
Services help maintain state consistency across different controllers.
Example – Sharing a Counter Value
app.factory('CounterService', function() {
var counter = 0;
return {
increment: function() { counter++; },
getCount: function() { return counter; }
};
});
app.controller('FirstController', function(CounterService) {
var vm = this;
vm.increment = function() {
CounterService.increment();
};
vm.count = function() {
return CounterService.getCount();
};
});
app.controller('SecondController', function(CounterService) {
var vm = this;
vm.count = function() {
return CounterService.getCount();
};
});
<div ng-controller="FirstController as firstCtrl">
<button ng-click="firstCtrl.increment()">Increment</button>
<p>First Controller Count: {{ firstCtrl.count() }}</p>
</div>
<div ng-controller="SecondController as secondCtrl">
<p>Second Controller Count: {{ secondCtrl.count() }}</p>
</div>
Why Use a Service Here?
- Maintains shared state between controllers.
