As I understand it, when inside a factory I return an object that gets injected into a controller. When inside a service I am dealing with the object using this
This would be the best and short answer for understanding Service Vs Factory Vs Provider
Source: https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J
Here what ben says with a demo http://jsbin.com/ohamub/1/edit?html,output
"There are comments in the code illustrating the primary differences but I will expand on them a bit here. As a note, I am just getting my head around this so if I say anything that is wrong please let me know.
Services
Syntax: module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided the actual function reference passed to module.service.
Usage: 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.
Factories
Syntax: module.factory( 'factoryName', function );
Result: When declaring factoryName as an injectable argument you will be provided the value that is returned by invoking the function reference passed to module.factory.
Usage: Could be useful for returning a 'class' function that can then be new'ed to create instances.
Providers
Syntax: module.provider( 'providerName', function );
Result: When declaring providerName as an injectable argument you will be provided the value that is returned by invoking the $get method of the function reference passed to module.provider.
Usage: Could be useful for returning a 'class' function that can then be new'ed to create instances but that requires some sort of configuration before being injected. Perhaps useful for classes that are reusable across projects? Still kind of hazy on this one." Ben
I had this confusion for a while and I'm trying my best to provide a simple explanation here. Hope this will help!
angular .factory
and angular .service
both are used to initialize a service and work in the same way.
The only difference is, how you want to initialize your service.
Both are Singletons
var app = angular.module('app', []);
<service name>
, <function with a return value>
)If you would like to initialize your service from a function that you have with a return value, you have to use this factory
method.
e.g.
function myService() {
//return what you want
var service = {
myfunc: function (param) { /* do stuff */ }
}
return service;
}
app.factory('myService', myService);
When injecting this service (e.g. to your controller):
myService()
) to return the object<service name>
, <constructor function>
)If you would like to initialize your service from a constructor function (using this
keyword), you have to use this service
method.
e.g.
function myService() {
this.myfunc: function (param) { /* do stuff */ }
}
app.service('myService', myService);
When injecting this service (e.g. to your controller):
new
ing your given function (as new myService()
) to return the objectfactory
with <constructor function>
or service
with <function with a return value>
, it will not work.
This is what helped me to understand the difference, thanks to a blog post by Pascal Precht.
A service is a method on a module that takes a name and a function that defines the service. You can inject and use that particular service in other components, like controllers, directives and filters. A factory is a method on a module and it also takes a name and a function, that defines the factory. We can also inject and use the it same way we did with the service.
Objects created with new use the value of the prototype property of their constructor function as their prototype, so I found the Angular code that calls Object.create(), that I believe is the service constructor function when it gets instantiated. However, a factory function is really just a function that gets called, which is why we have to return an object literal for the factory.
Here is the angular 1.5 code I found for factory:
var needsRecurse = false;
var destination = copyType(source);
if (destination === undefined) {
destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
needsRecurse = true;
}
Angular source code snippet for the factory() function:
function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}
It takes the name and the factory function that is passed and returns a provider with the same name, that has a $get method which is our factory function. Whenever you ask the injector for a specific dependency, it basically asks the corresponding provider for an instance of that service, by calling the $get() method. That’s why $get() is required, when creating providers.
Here is the angular 1.5 code for service.
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
It turns out that when we call service(), it actually calls factory()! However, it doesn’t just pass our service constructor function to the factory as is. It also passes a function that asks the injector to instantiate an object by the given constructor.
In other words, if we inject MyService somewhere, what happens in the code is:
MyServiceProvider.$get(); // return the instance of the service
To restate it again, a service calls a factory, which is a $get() method on the corresponding provider. Moreover, $injector.instantiate() is the method that ultimately calls Object.create() with the constructor function. That’s why we use "this" in services.
For ES5 it doesn't matter which we use: service() or factory(), it’s always a factory that is called which creates a provider for our service.
You can do the exact same thing with services as well though. A service is a constructor function, however, that doesn’t prevent us from returning object literals. So we can take our service code and write it in a way that it basically does the exact same thing as our factory or in other words, you can write a service as a factory to return an object.
Why do most people recommend to use factories over services? This is the best answer I've seen which comes from Pawel Kozlowski's book: Mastering Web Application Development with AngularJS.
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."
this
keyword to define
function.$get
you define and it can be used to get the object that returns
the data.All angular services are singletons:
Docs (see Services as singletons): https://docs.angularjs.org/guide/services
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.
Basically the difference between the service and factory is as follows:
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
Adding to the first answer, I think .service() is for people who have written their code in more object oriented style(C#/Java) (using this keyword and instantiating object via prototype/Constructor function).
Factory is for developers who write code which is more natural to javascript/functional style of coding.
Take a look at the source code of .service and .factory method inside angular.js - internally they all call provider method:
function provider(name, provider_) {
if (isFunction(provider_)) {
provider_ = providerInjector.instantiate(provider_);
}
if (!provider_.$get) {
throw Error('Provider ' + name + ' must define $get factory method.');
}
return providerCache[name + providerSuffix] = provider_;
}
function factory(name, factoryFn) { \
return provider(name, { $get: factoryFn });
}
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}