Ashish Singh
aitashish173@gmail.com
@ashishait
@ashish173
Services
Naming
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
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 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
Thank you
Questions?