Services & Factories
Services and Factories are objects Angular injectables that we use to create objects. They are very similar to one another and are often used interchangeably.
- Service and factories both yield singleton objects.
- Once created this object will persist and you will get the same object back each time you request it.
- We can inject services and factories into controllers using DI.
A Service
We compose a service by giving Angular a newable function (one which writes to "this").
angular.module('app')
.service('helloService', function() {
this.sayHello = function() {
alert("Hello");
};
});
A Factory
A factory on the other hand composes an object and returns it:
angular.module('app')
.service('helloFactory', function() {
return {
sayHello: function() {
alert("Hello");
}
};
});
Making use of factories and services
Once we declare them, services and factories become injectable. Let's inject them into a controller:
angular.module('app')
.controller('myController', function(helloService, helloFactory) {
helloService.sayHello();
helloFactory.sayHello();
})
Services as API accessors
Services are often used as API accessors to take API code out of a controller and keep the controller focussed on $scope.
Here is a service that can talk to Github:
angular.module('app', [])
.service('github', function( $http ) {
var url = 'https://api.github.com/events?callback=JSON_CALLBACK';
this.getEvents = function () {
return $http.jsonp(url);
}
});
Further Reading
For more on the technical and conceptual differences between services and factories, read my Stack Overflow post here:
Flickr Service
We are going to refactor our Flickr exercise to use a service. If you didn't complete the Flickr exercise, you can download some sample code from here (look in the exercise section)
- Create a Flickr service, that encapsulates the AJAX logic needed to pull data from the Flickr API. Return the $http object so that we can apply callbacks. You can use the code above as a template.
- Return to your Flickr exercise. Inject the Flickr service into your controller and use this instead.
Further Exercise - Simple shopping cart service
- Create a service to manage a shopping cart. Give it a cart variable which holds an array of objects.
- Add an addToCart function to the service which pushes an item into the cart.
- Write a controller to display the cart. Inject the cart into your controller.
- In your controller, write a simple method on $scope which calls shoppingCart.addToCart.
- In your controller, create an attribute of $scope that holds the shoppingCart.cart.
- Write a view to render the cart.