1) Services
A service is a constructor
function that is invoked once at runtime with new
, just like what we would do with plain javascript with only
difference that AngularJs
is calling the new
behind the scenes.
There is one thumb rule to remember in case of services
new
Lets see a simple example where we would register a service which uses $http
service to fetch student details, and use it in the controller
function StudentDetailsService($http) {
this.getStudentDetails = function getStudentDetails() {
return $http.get('/details');
};
}
angular.module('myapp').service('StudentDetailsService', StudentDetailsService);
We just inject this service into the controller
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
When to use?
Use .service()
wherever you want to use a constructor. It is usually used to create public API's just like getStudentDetails()
. But if you
don't want to use a constructor and wish to use a simple API pattern instead, then there isn't much flexibility in .service()
.
2) Factory
Even though we can achieve all the things using .factory()
which we would, using .services()
, it doesn't make .factory()
"same as" .service()
.
It is much more powerful and flexible than .service()
A .factory()
is a design pattern which is used to return a value.
There are two thumb rules to remember in case of factories
Lets see some examples on what we can do using .factory()
Returning Objects Literals
Lets see an example where factory is used to return an object using a basic Revealing module pattern
function StudentDetailsService($http) {
function getStudentDetails() {
return $http.get('/details');
}
return {
getStudentDetails: getStudentDetails
};
}
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
Usage inside a controller
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
Returning Closures
What is a closure?
Closures are functions that refer to variables that are used locally, BUT defined in an enclosing scope.
Following is an example of a closure
function closureFunction(name) {
function innerClosureFunction(age) { // innerClosureFunction() is the inner function, a closure
// Here you can manipulate 'age' AND 'name' variables both
};
};
The "wonderful" part is that it can access the name
which is in the parent scope.
Lets use the above closure example inside .factory()
function StudentDetailsService($http) {
function closureFunction(name) {
function innerClosureFunction(age) {
// Here you can manipulate 'age' AND 'name' variables
};
};
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
Usage inside a controller
function StudentController(StudentDetailsService) {
var myClosure = StudentDetailsService('Student Name'); // This now HAS the innerClosureFunction()
var callMyClosure = myClosure(24); // This calls the innerClosureFunction()
};
angular.module('app').controller('StudentController', StudentController);
Creating Constructors/instances
.service()
creates constructors with a call to new
as seen above. .factory()
can also create constructors with a call to new
Lets see an example on how to achieve this
function StudentDetailsService($http) {
function Student() {
this.age = function () {
return 'This is my age';
};
}
Student.prototype.address = function () {
return 'This is my address';
};
return Student;
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
Usage inside a controller
function StudentController(StudentDetailsService) {
var newStudent = new StudentDetailsService();
//Now the instance has been created. Its properties can be accessed.
newStudent.age();
newStudent.address();
};
angular.module('app').controller('StudentController', StudentController);