AngularJS : Factory and Service?
Service vs Factory
The difference between factory and service is just like the difference between a function and an object
Factory Provider
Gives us the function's return value ie. You just create an object, add properties to it, then return that same object.When you pass this service into your controller, those properties on the object will now be available in that controller through your factory. (Hypothetical Scenario)
Singleton and will only be created once
Reusable components
Factory are a great way for communicating between controllers like sharing data.
Can use other dependencies
Usually used when the service instance requires complex creation logic
Cannot be injected in
.config()
function.Used for non configurable services
If you're using an object, you could use the factory provider.
Syntax:
module.factory('factoryName', function);
Gives us the instance of a function (object)- You just instantiated with the ‘new’ keyword and you’ll add properties to ‘this’ and the service will return ‘this’.When you pass the service into your controller, those properties on ‘this’ will now be available on that controller through your service. (Hypothetical Scenario)
Singleton and will only be created once
Reusable components
Services are used for communication between controllers to share data
You can add properties and functions to a service object by using the
this
keywordDependencies are injected as constructor arguments
Used for simple creation logic
Cannot be injected in
.config()
function.If you're using a class you could use the service provider
Syntax:
module.service(‘serviceName’, function);
In below example I have define MyService
and MyFactory
. Note how in .service
I have created the service methods using this.methodname.
In .factory
I have created a factory object and assigned the methods to it.
AngularJS .service
module.service('MyService', function() {
this.method1 = function() {
//..method1 logic
}
this.method2 = function() {
//..method2 logic
}
});
AngularJS .factorymodule.factory('MyFactory', function() {
var factory = {};
factory.method1 = function() {
//..method1 logic
}
factory.method2 = function() {
//..method2 logic
}
return factory;
});
Also Take a look at this beautiful stuffs
Confused about service vs factory
AngularJS Factory, Service and Provider
Angular.js: service vs provider vs factory?
AngularJS: Service vs provider vs factory
From the AngularJS mailing list I got an amazing thread that explains service vs factory vs provider and their injection usage. Compiling the answers:
Services
Syntax:module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided with an instance of the function. In other words
new FunctionYouPassedToService()
.Factories
Syntax:module.factory( 'factoryName', function );
Result: When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory.
Providers
Syntax:module.provider( 'providerName', function );
Result: When declaring providerName as an injectable argument you will be provided with
(new ProviderFunction()).$get()
. The constructor function is instantiated before the $get method is called - ProviderFunction
is the function reference passed to module.provider.Providers have the advantage that they can be configured during the module configuration phase.
See here for the provided code.
Here's a great further explanation by Misko:
provide.value('a', 123);
function Controller(a) {
expect(a).toEqual(123);
}
In this case the injector simply returns the value as is. But what if you want to compute the value? Then use a factoryprovide.factory('b', function(a) {
return a*2;
});
function Controller(b) {
expect(b).toEqual(246);
}
So factory
is a function which is responsible for creating the value. Notice that the factory function can ask for other dependencies.But what if you want to be more OO and have a class called Greeter?
function Greeter(a) {
this.greet = function() {
return 'Hello ' + a;
}
}
Then to instantiate you would have to writeprovide.factory('greeter', function(a) {
return new Greeter(a);
});
Then we could ask for 'greeter' in controller like thisfunction Controller(greeter) {
expect(greeter instanceof Greeter).toBe(true);
expect(greeter.greet()).toEqual('Hello 123');
}
But that is way too wordy. A shorter way to write this would be provider.service('greeter', Greeter);
But what if we wanted to configure the Greeter
class before the injection? Then we could write
provide.provider('greeter2', function() {
var salutation = 'Hello';
this.setSalutation = function(s) {
salutation = s;
}
function Greeter(a) {
this.greet = function() {
return salutation + ' ' + a;
}
}
this.$get = function(a) {
return new Greeter(a);
};
});
Then we can do this:angular.module('abc', []).config(function(greeter2Provider) {
greeter2Provider.setSalutation('Halo');
});
function Controller(greeter2) {
expect(greeter2.greet()).toEqual('Halo 123');
}
As a side note, service
, factory
, and value
are all derived from provider.provider.service = function(name, Class) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.instantiate(Class);
};
});
}
provider.factory = function(name, factory) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.invoke(factory);
};
});
}
provider.value = function(name, value) {
provider.factory(name, function() {
return value;
});
};
AngularJS : When to use service instead of factory
Explanation
You got different things here:
First:
- If you use a service you will get the instance of a function ("
this
"
keyword). - If you use a factory you will get the value that is returned by
invoking the function reference (the return statement in factory).
Second:
Keep in mind all providers in AngularJS (value, constant, services, factories) are singletons!
Third:
Using one or the other (service or factory) is about code style.
But, the common way in AngularJS is to use factory.
Why ?
(ref: http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821).Because "The factory method is the most common way of getting objects into AngularJS dependency injection system. It is very flexible and can contain sophisticated creation logic. Since factories are regular functions, we can also take advantage of a new lexical scope to simulate "private" variables. This is very useful as we can hide implementation details of a given service."
Usage
Service : Could be useful for sharing utility functions that are useful to invoke by simply appending ()
to the injected function reference. Could also be run with injectedArg.call(this)
or similar.
Factory : Could be useful for returning a ‘class’ function that can then be new`ed to create instances.
So, use a factory when you have complex logic in your service and you don't want expose this complexity.
In other cases if you want to return an instance of a service just use service.
But you'll see with time that you'll use factory in 80% of cases I think.
For more details: http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/
UPDATE :
Excellent post here :
http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html
"If you want your function to be called like a normal function, use
factory. If you want your function to be instantiated with the new
operator, use service. If you don't know the difference, use factory."
UPDATE :
AngularJS team does his work and give an explanation:
http://docs.angularjs.org/guide/providers
And from this page :
"Factory and Service are the most commonly used recipes. The only difference between them is that Service recipe works better for objects of custom type, while Factory can produce JavaScript primitives and functions."
Difference between service and factory
- Both are singleton
- They differ in terms of writing pattern
- My personnel choice is to use service
Angular JS factory vs service vs provider by example
Short answer: The author chose Provider to make the defaults 'read-only'. The code could still work if they hadn't used Provider, but Provider is cleaner and 'safer'
Provider
, Service
, and Factory
are all the same basic thing in Angular, just with different APIs; Provider
can kinda be thought of as the 'base' element, but they all have the same end purpose: to create an Angular injectable. Each of those injectables has a Provider that provides the blueprint (Angular looks for a $get
method), and a Singleton instance the provider generates. If you use Factory
or Service
, Angular does work behind the scenes so you don't need to know all the details; you'll just have a really boring Provider
that only does the basics. However, if you use Provider
yourself, you can put extra properties and functions on it in your declaration.
You can inject Providers
into a module's config()
method, which is run before any of the Singletons are created. Try looking here for a longer explanation.
In AngularStrap, the author puts a 'defaults' object on the Provider. The author expects you to modify that object in your module's config()
method, and then Angular will generate the Singleton. However, the 'defaults' object is not on the Singleton, so you can't change the defaults once the app is 'running'. Even if you inject the Provider
again somewhere and change 'default's again, Angular won't re-make your Singleton, so the defaults effectively become 'read-only'. This is a good practice to prevent code from making unwanted changes, especially when you have multiple people in the same code, or you know other people will be using your module.
You may see other code that doesn't work like that... maybe another app just uses a factory
, and puts the 'defaults' object on that factory. It would still 'work', and the code would look a lot like it does currently. However, because 'defaults' would be directly on the Singleton, your code could change these settings at ANY point if somebody wrote code to do it. Now you've got to leave comments and documentation explaining when to change the defaults, when NOT to change the defaults, and so on; for 99% of cases, the defaults never need to change once the app is running, so using Provider
and module.config()
is safe and straightforward.
Confused about Service vs Factory
All angular services are singletons:
Docs (see Services as singletons): https://docs.angularjs.org/guide/services
Basically the difference between the service and factory is as follows:Lastly, it is important to realize that all Angular services are application singletons. This means that there is only one instance of a given service per injector.
app.service('myService', function() {
// service is just a constructor function
// that will be called with 'new'
this.sayHello = function(name) {
return "Hi " + name + "!";
};
});
app.factory('myFactory', function() {
// factory returns an object
// you can run some code before
return {
sayHello : function(name) {
return "Hi " + name + "!";
}
}
});
Check out this presentation about $provide: http://slides.wesalvaro.com/20121113/#/Those slides were used in one of the AngularJs meetups: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html
AngularJS : factory $http service
The purpose of moving your studentSessions
service out of your controller is to achieve separation of concerns. Your service's job is to know how to talk with the server and the controller's job is to translate between view data and server data.
But you are confusing your asynchronous handlers and what is returning what. The controller still needs to tell the service what to do when the data is received later...
studentApp.factory('studentSession', function($http){
return {
getSessions: function() {
return $http.post('/services', {
type : 'getSource',
ID : 'TP001'
});
}
};
});
studentApp.controller('studentMenu',function($scope, studentSession){
$scope.variableName = [];
var handleSuccess = function(data, status) {
$scope.variableName = data;
console.log($scope.variableName);
};
studentSession.getSessions().success(handleSuccess);
});
AngularJS services vs factory advantages and shortcomings
Service vs Factory
The difference between factory and service is just like the difference between a function
and an object
Factory Provider
Gives us the function's return value ie. You just create an object, add properties to it, then return that same object.When you pass this service into your controller, those properties on the object will now be available in that controller through your factory. (Hypothetical Scenario)
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.
Syntax:
module.factory('factoryName', function);
Gives us the instance of a function (object)- You just instantiated with the ‘new’ keyword and you’ll add properties to ‘this’ and the service will return ‘this’.When you pass the service into your controller, those properties on ‘this’ will now be available on that controller through your service. (Hypothetical Scenario)
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
Syntax:
module.service(‘serviceName’, function);
MyService
and MyFactory
. Note how in .service
I have created the service methods using this.methodname.
In .factory
I have created a factory object and assigned the methods to it.AngularJS .service
module.service('MyService', function() {
this.method1 = function() {
//..
return functionValue;
}
this.method2 = function() {
//..
return functionValue;
}
});
AngularJS .factorymodule.factory('MyFactory', function() {
var factory = {};
factory.method1 = function() {
//..
}
factory.method2 = function() {
//..
}
return factory;
});
Also Take a look at this beautiful stuffs
Confused about service vs factory
AngularJS Factory, Service and Provider
Angular.js: service vs provider vs factory?
angular.service vs angular.factory
angular.service('myService', myServiceFunction);
angular.factory('myFactory', myFactoryFunction);
I had trouble wrapping my head around this concept until I put it to myself this way:
Service: the function that you write will be new-ed:
myInjectedService <---- new myServiceFunction()
Factory: the function (constructor) that you write will be invoked: myInjectedFactory <--- myFactoryFunction()
What you do with that is up to you, but there are some useful patterns...Such as writing a service function to expose a public API:
function myServiceFunction() {
this.awesomeApi = function(optional) {
// calculate some stuff
return awesomeListOfValues;
}
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();
Or using a factory function to expose a public API:
function myFactoryFunction() {
var aPrivateVariable = "yay";
function hello() {
return "hello mars " + aPrivateVariable;
}
// expose a public API
return {
hello: hello
};
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.hello = myInjectedFactory.hello();
Or using a factory function to return a constructor:
function myFactoryFunction() {
return function() {
var a = 2;
this.a2 = function() {
return a*2;
};
};
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();
Which one to use?...
You can accomplish the same thing with both. However, in some cases the factory gives you a little bit more flexibility to create an injectable with a simpler syntax. That's because while myInjectedService must always be an object, myInjectedFactory can be an object, a function reference, or any value at all. For example, if you wrote a service to create a constructor (as in the last example above), it would have to be instantiated like so:var myShinyNewObject = new myInjectedService.myFunction()
which is arguably less desirable than this:var myShinyNewObject = new myInjectedFactory();
(But you should be wary about using this type of pattern in the first place because new-ing objects in your controllers creates hard-to-track dependencies that are difficult to mock for testing. Better to have a service manage a collection of objects for you than use new()
wily-nilly.)One more thing, they are all Singletons...
Also keep in mind that in both cases, angular is helping you manage a singleton. Regardless of where or how many times you inject your service or function, you will get the same reference to the same object or function. (With the exception of when a factory simply returns a value like a number or string. In that case, you will always get the same value, but not a reference.)Related Topics
Adding New Data to Firebase Users
Add Two Functions to Window.Onload
How to Parse a Date in Format "Yyyymmdd" in JavaScript
Get Selected Value/Text from Select on Change
Render Object Properties in React
Backbone: Why Assign '$('#Footer')' to 'El'
JavaScript Replace() Method Dollar Signs
Passing a PHP Variable to JavaScript in a Blade Template
Handling Key-Press Events (F1-F12) Using JavaScript and Jquery, Cross-Browser
Options for Testing Service Workers via Http
Execute an Exe File Using Node.Js
How to Sign into Google with Selenium Automation Because of "This Browser or App May Not Be Secure."
How to Catch Jquery $.Getjson (Or $.Ajax with Datatype Set to 'JSONp') Error When Using JSONp
Should Github Be Used as a Cdn for JavaScript Libraries
How to Change the Pop-Up Position of the Jquery Datepicker Control
Using Jquery to Compare Two Arrays of JavaScript Objects
Why Is 'Event' Variable Available Even When Not Passed as a Parameter