Angularjs
Ashish Singh
aitashish173@gmail.com
@ashishait
@ashish173
Services, providers & factories



Services
- Recipes for making development easy
- Api is defined by developer
- Objects Instantiated and wired together for the app to work
- Initialized only once after that reference is used in the app.
Naming
- Its messed up....
- General name 'service'
- Yet a service is named 'service'
- Angular team has apologized for it.
Value recipe
Simple values for applications
Can be injected throughout the application
Value recipe
angular.module('nuclearApp')
nuclearApp.value('radiationLevel', '2.5677788');
nuclearApp.controller('ExplodeCtrl', ['radationLevel',
function ExplodeCtrl(radiationLevel) {
console.log('Radiation level', radiationlevel);
// 2.5677788
}]);
Initialization
Use
Factory recipe
-
Gives us the function's return value ie. You just create an object, add properties to it, then return that same object
-
Singleton
-
Reusable components
-
Can use other dependencies
-
Usually used when the service instance requires complex creation logic
-
Used for non configurable services
-
If you're using an object, you could use the factory provider.
Factory recipe
myApp.factory('NukeBomb', function(){
var factory = {};
return factory;
factory = {
triggerIgnition: function(){
return 'Bomb triggered';
}
}
});
nuclearApp.controller('ExplodeCtrl', ['NukeBomb',
function ExplodeCtrl(NukeBomb) {
NukeBomb.triggerIgnition();
}]);
Initialization
Use
Service recipe
-
Gives us the instance of a function (object)- instantiated with the ‘new’ keyword and you’ll add properties to ‘this’ and the service will return ‘this’
-
Singleton and will only be created once
-
Reusable components
-
Dependencies are injected as constructor arguments
-
Used for simple creation logic
-
If you're using a class you could use the service provider
Service recipe
myApp.service('NukeBomb', function(){
this.triggerIgnition: function(){
return 'bomb ignited';
},
this.drop: function(){
return 'bomb dropped awaiting explosion';
}
});
nuclearApp.controller('ExplodeCtrl', ['NukeBomb',
function ExplodeCtrl(NukeBomb) {
NukeBomb.triggerIgnition();
NukeBomb.dropBomb();
}]);
Initialization
Use
Provider recipe
- Core recipe type and all the other recipe types are just syntactic sugar on top of it.
- Implements a $get method.
- Use when exposing an API for application-wide configuration.
- Rethink if you end up using this in your app code.
Provider recipe
myApp.provider('NukeBomb', function(){
this.codeName = "Destroy ISIS";
this.$get = function(){
// any init vars here
return {
triggerIgnition: function(){
return 'bomb ignited';
},
drop: function(){
return 'bomb dropped awaiting explosion';
}
}
}
this.setCodeName = function(codeName){
this.codeName = codeName;
}
});
Initialization
Provider recipe
// Config time use
nuclearApp.config(function(NukeBombProvider){
NukeBombProvider.setCodeName = "Killer bomb";
});
// after run phase in controllers
nuclearApp.controller('ExplodeCtrl', ['NukeBomb',
function ExplodeCtrl(NukeBomb) {
NukeBomb.triggerIgnition();
NukeBomb.dropBomb();
}]);
Use
Main confusions
When to use a service or a factory?
Magic time
nuclearApp.service('NukeBomb', function(){
this.triggerIgnition: function(){
return 'bomb ignited';
},
this.drop: function(){
return 'bomb dropped awaiting explosion';
}
});
// Looks like a factory
nuclearApp.service('NukeBomb', function(){
var killerService;
return killerService;
killerService = {
triggerIgnition: function(){
return 'bomb ignited';
},
drop: function(){
return 'bomb dropped awaiting explosion';
}
}
});
Services can act as factories
Text
Services can act as factories and vice versa.
In angularjs you don't need factories at all services can do all magic for you.
Main distinction
Factories
While injecting you have the instance of the function. In other words new FunctionYouPassedToService()
Services
While injecting you have the value that is returned by invoking the function reference passed to module.factory
Main distinction
Factories
DI using “service”, this creates a new GLOBAL instance of the “Service” object and injects it in to the function.
Services
DI using “factory” it does not create an instance. It just passes the method and later the consumer internally has to make calls to the factory for object instances.
Use cases
- Share data b/w controllers
- Exposing api eg. library
- Common code
- Constants
- Config time initialization(Providers)
Share data b/w Ctrls
NuclearApp.factory('ConfidentialData', function () {
var confidentialData = {
groundZero: '',
codeName: ''
};
return {
getGroundZero: function () {
return confidentialData.groundZero;
},
setGroundZero: function (altitude) {
confidentialData.groundZero = altitude;
},
getCodeName: function () {
return confidentialData.groundZero;
},
setCodeName: function (name) {
confidentialData.codeName = name;
}
};
});
Share data b/w Ctrls
NuclearApp.controller('FirstCtrl', function ($scope, ConfidentialData) {
$scope.codeName = '';
$scope.$watch('firstName', function (newValue, oldValue) {
if (newValue !== oldValue) ConfidentialData.codeName(newValue);
});
});
Using getters/setters in Controllers
Exposing api(Library)
angular.module('ngAuth', [])
.provider('$auth', function() {
var config = {
permissions: [],
customInit: {}
};
// adding extra permission if passed by user
this.permission = function(permissions){
config.permissions.push(permissions);
return this;
}
// implement $get method
this.$get = ['$q', '$rootScope', '$window', '$http', function($q, $rootScope, $window, $http){
$auth = $q.defer();
/* `property` object should have
* api_url as an attribute
* it will be used to make api call for login
*/
$auth.config = function(property){
if(property.api_url != undefind) {
config['api_url']= property.api_url;
}
return config;
};
}];
};
Using providers
Common code
MyApp.service(Helper, function(){
this.currentDate = function(){
return new Date();
};
this.currentScore = funtion(){
$http.get('some_url', {options})
.$promise
.then(function(response){
return response.data;
})
.catch(function(error){
// error occured
});
};
});
MyApp.controller(Ctrl1, function(Helper){
var vm = this;
vm.today = Helper.currentDate();
// this helper method can be shared across multiple controllers
});
Config time init
MyApp.provider(Killer, function(){
this.name = "Default name";
this.$get = function(){
var name = this.name;
return {
getName = function(){
return name;
},
setName = function(name){
name = name;
}
};
};
});
MyApp.config('KillerProvider' function(KillerProvider){
KillerProvider.setName('Assasin 2');
// Above defined provider is accessible in config phase as KillerProvider
});
Conclusion
- Services and factories are both general js recipe
- They can be used as per need
- Conventionally factory -> object related tasks.
- Services -> class related tasks.
- Providers -> Exposing api
Thank you
Questions?
Angularjs services/providers/factrories
By Ashish Singh
Angularjs services/providers/factrories
- 2,800