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
and not returning anything.
I was under the assumption that a service was always a singleton, and that a new factory object gets injected in every controller. However, as it turns out, a factory object is a singleton too?
Example code to demonstrate:
var factories = angular.module('app.factories', []);
var app = angular.module('app', ['ngResource', 'app.factories']);
factories.factory('User', function () {
return {
first: 'John',
last: 'Doe'
};
});
app.controller('ACtrl', function($scope, User) {
$scope.user = User;
});
app.controller('BCtrl', function($scope, User) {
$scope.user = User;
});
When changing user.first
in ACtrl
it turns out that user.first
in BCtrl
is also changed, e.g. User
is a singleton?
My assumption was that a new instance was injected in a controller with a factory?
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
For me the revelation came when I realise that they all work the same way: by running something once, storing the value they get, and then cough up that same stored value when referenced through Dependency Injection.
Say we have:
app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);
The difference between the three is that:
a's stored value comes from running fn , in other words: fn() b’s stored value comes from newing fn, in other words: new fn() c’s stored value comes from first getting an instance by newing fn, and then running a $get method of the instance
which means, there’s something like a cache object inside angular, whose value of each injection is only assigned once, when they've been injected the first time, and where:
cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()
This is why we use this
in services, and define a this.$get
in providers.
Hope this helps.
.service
and .factory
are shortcuts for .provide
. In the end all services come from calling .$get()
.
live example
" hello world " example
with factory
/ service
/ provider
:
var myApp = angular.module('myApp', []);
//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});
//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
return {
sayHello: function() {
return "Hello, World!"
}
};
});
//provider style, full blown, configurable version
myApp.provider('helloWorld', function() {
// In the provider function, you cannot inject any
// service or factory. This can only be done at the
// "$get" method.
this.name = 'Default';
this.$get = function() {
var name = this.name;
return {
sayHello: function() {
return "Hello, " + name + "!"
}
}
};
this.setName = function(name) {
this.name = name;
};
});
//hey, we can configure a provider!
myApp.config(function(helloWorldProvider){
helloWorldProvider.setName('World');
});
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
$scope.hellos = [
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];
}
There is also a way to return a constructor function so you can return newable classes in factories, like this:
function MyObjectWithParam($rootScope, name) {
this.$rootScope = $rootScope;
this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
return this.name;
};
App.factory('MyObjectWithParam', function ($injector) {
return function(name) {
return $injector.instantiate(MyObjectWithParam,{ name: name });
};
});
So you can do this in a controller, which uses MyObjectWithParam:
var obj = new MyObjectWithParam("hello"),
See here the full example:
http://plnkr.co/edit/GKnhIN?p=preview
And here the google group pages, where it was discussed:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ
App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]);
Read more about it here: docs.angularjs.org/tutorial/step_05
.service
instead?
.factory
as opposed to .service
?
new Car('BMW')
and new Car('Ford')
and they don't share the same variables and everything.
Here are the primary differences:
Services
Syntax: module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided with the instance of a function 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.
Also check AngularJS documentation and similar question on stackoverflow confused about service vs factory.
Here is example using services and factory. Read more about AngularJS service vs factory.
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);
}]);
}
Very simply:
.service - registered function will be invoked as a constructor (aka 'newed')
.factory - registered function will be invoked as a simple function
Both get invoked once resulting in a singleton object that gets injected into other components of your app.
All providers work the same way. The different methods service
, factory
, provider
just let you accomplish the same thing in less code.
P.S. There's also value
and constant
.
Each special case down the chain starting with provider
and ending with value
has an added limitation. So to decide between them you have to ask yourself which let's you accomplish what you want with less code.
Here is a picture that shows you what I mean:
https://i.stack.imgur.com/CkdHl.png
You can a breakdown and reference guide on the blog post I got this image from:
console.log()
and injecting into multiple controllers.
Here are some more examples of services vs factories which may be useful in seeing the difference between them. Basically, a service has "new ..." called on it, it is already instantiated. A factory is not instantiated automatically.
Basic Examples
Return a class object which has a single method
Here is a service that has a single method:
angular.service('Hello', function () {
this.sayHello = function () { /* ... */ };
});
Here is a factory that returns an object with a method:
angular.factory('ClassFactory', function () {
return {
sayHello: function () { /* ... */ }
};
});
Return a value
A factory that returns a list of numbers:
angular.factory('NumberListFactory', function () {
return [1, 2, 3, 4, 5];
});
console.log(NumberListFactory);
A service that returns a list of numbers:
angular.service('NumberLister', function () {
this.numbers = [1, 2, 3, 4, 5];
});
console.log(NumberLister.numbers);
The output in both cases is the same, the list of numbers.
Advanced Examples
"Class" variables using factories
In this example we define a CounterFactory, it increments or decrements a counter and you can get the current count or get how many CounterFactory objects have been created:
angular.factory('CounterFactory', function () {
var number_of_counter_factories = 0; // class variable
return function () {
var count = 0; // instance variable
number_of_counter_factories += 1; // increment the class variable
// this method accesses the class variable
this.getNumberOfCounterFactories = function () {
return number_of_counter_factories;
};
this.inc = function () {
count += 1;
};
this.dec = function () {
count -= 1;
};
this.getCount = function () {
return count;
};
}
})
We use the CounterFactory
to create multiple counters. We can access the class variable to see how many counters were created:
var people_counter;
var places_counter;
people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());
console.log('counters', people_counter.getNumberOfCounterFactories());
places_counter = new CounterFactory();
console.log('places', places_counter.getCount());
console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());
The output of this code is:
people 0
people 1
counters 1
places 0
counters 2
counters 2
“Factory” and “Service” are different ways of doing DI (Dependency injection) in angular.
So when we define DI using “service” as shown in the code below. This creates a new GLOBAL instance of the “Logger” object and injects it in to the function.
app.service("Logger", Logger); // Injects a global object
When you define DI using a “factory” it does not create a instance. It just passes the method and later the consumer internally has to make calls to the factory for object instances.
app.factory("Customerfactory", CreateCustomer);
Below is a simple image which shows visually how DI process for “Service” is different than “Factory”.
https://i.stack.imgur.com/M55Yi.png
Factory should be used When we want to create different types of objects depending on scenarios. For example depending on scenario we want to create a simple “Customer” object , or “Customer” with “Address” object or “Customer” with “Phone” object. Here is a detailed explanation of this paragraph
Service should be used When we have utility or shared functions to be injected like Utility , Logger , Error handler etc.
Service style: (probably the simplest one) returns the actual function: Useful for sharing utility functions that are useful to invoke by simply appending () to the injected function reference.
A service in AngularJS is a singleton JavaScript object which contains a set of functions
var myModule = angular.module("myModule", []);
myModule.value ("myValue" , "12345");
function MyService(myValue) {
this.doIt = function() {
console.log("done: " + myValue;
}
}
myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {
myService.doIt();
});
Factory style: (more involved but more sophisticated) returns the function's return value: instantiate an object like new Object() in java.
Factory is a function that creates values. When a service, controller etc. needs a value injected from a factory, the factory creates the value on demand. Once created, the value is reused for all services, controllers etc. which need it injected.
var myModule = angular.module("myModule", []);
myModule.value("numberValue", 999);
myModule.factory("myFactory", function(numberValue) {
return "a value: " + numberValue;
})
myModule.controller("MyController", function($scope, myFactory) {
console.log(myFactory);
});
Provider style: (full blown, configurable version) returns the output of the function's $get function: Configurable.
Providers in AngularJS is the most flexible form of factory you can create. You register a provider with a module just like you do with a service or factory, except you use the provider() function instead.
var myModule = angular.module("myModule", []);
myModule.provider("mySecondService", function() {
var provider = {};
var config = { configParam : "default" };
provider.doConfig = function(configParam) {
config.configParam = configParam;
}
provider.$get = function() {
var service = {};
service.doService = function() {
console.log("mySecondService: " + config.configParam);
}
return service;
}
return provider;
});
myModule.config( function( mySecondServiceProvider ) {
mySecondServiceProvider.doConfig("new config param");
});
myModule.controller("MyController", function($scope, mySecondService) {
$scope.whenButtonClicked = function() {
mySecondService.doIt();
}
});
The basic difference, is that provider allows to set primitive (non-objects), array, or callback function values into the factory declared variable, and thus if returning an object it has to be explicitly declared and returned.
On the other hand a service can only be used to set the service declared variable to an object, thus we can avoid the explicit creation and returning of the objects, while on the other hand it allows usage of the this keyword.
Or in short words "provider is a more generic form while service is limited to objects only".
This is how I understood the difference between them in terms of design patterns:
Service: Return a type, that will be newed to create an object of that type. If Java analogy is used, Service returns a Java Class definition.
Factory: Returns a concrete object that can be immediately used. In Java Analogy a Factory returns a Java Object.
The part that often confuses people (including myself) is that when you inject a Service or a Factory in your code they can be used the same way, what you get in your code in both cases is a concrete object that you can immediately invoke. Which means in case of the Service, angular calls "new" on the service declaration on behalf of you. I think this is a convoluted concept.
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', []);
Factory
app.factory(
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):
Angular will call your given function (as myService()) to return the object
Singleton - called only once, stored, and pass the same object.
Service
app.service(
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):
Angular will newing your given function (as new myService()) to return the object
Singleton - called only once, stored, and pass the same object.
factory
service
Examples - DEMOs
Angular Service vs Factory
Angular Service vs Factory (with route)
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."
With the factory you actually create an object inside of the factory and return it.
With the service you just have a standard function that uses the this keyword to define function.
With the provider there’s a $get you define and it can be used to get the object that returns the data.
There are three ways of handling business logic in AngularJS: (Inspired by Yaakov's Coursera AngularJS course) which are:
Service Factory Provider
Here we are only going to talk about Service vs Factory
SERVICE:
Syntax:
app.js
var app = angular.module('ServiceExample',[]);
var serviceExampleController =
app.controller('ServiceExampleController', ServiceExampleController);
var serviceExample = app.service('NameOfTheService', NameOfTheService);
ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files
function ServiceExampleController(NameOfTheService){
serviceExampleController = this;
serviceExampleController.data = NameOfTheService.getSomeData();
}
function NameOfTheService(){
nameOfTheService = this;
nameOfTheService.data = "Some Data";
nameOfTheService.getSomeData = function(){
return nameOfTheService.data;
}
}
index.html
<div ng-controller = "ServiceExampleController as serviceExample">
{{serviceExample.data}}
</div>
The main features of Service:
Lazily Instantiated: If the service is not injected it won't be instantiated ever. So to use it you will have to inject it to a module. Singleton: If it is injected to multiple modules, all will have access to only one particular instance. That is why, it is very convenient to share data across different controllers.
FACTORY
Now let's talk about the Factory in AngularJS
First let's have a look at the syntax:
app.js:
var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);
//first implementation where it returns a function
function NameOfTheFactoryOne(){
var factory = function(){
return new SomeService();
}
return factory;
}
//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
var factory = {
getSomeService : function(){
return new SomeService();
}
};
return factory;
}
Now using the above two in the controller:
var factoryOne = NameOfTheFactoryOne() //since it returns a function
factoryOne.someMethod();
var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
factoryTwo.someMethod();
Features of Factory:
This types of services follow the factory design pattern. The factory can be thought of as a central place that creates new objects or methods. This does not only produce singleton, but also customizable services. The .service() method is a factory that always produces the same type of service, which is a singleton. There is no easy way to configure it's behavior. That .service() method is usually used as a shortcut for something that doesn't require any configuration whatsoever.
For short and simple explanation refer https://stackoverflow.com/a/26924234/5811973.
For detailed explanation refer https://stackoverflow.com/a/15666049/5811973.
https://i.stack.imgur.com/24jgv.png
You can understand the difference with this analogy - Consider the difference between a normal function that will return some value and constructor function that will get instantiated using new keyword.So creating factory is just similar to create normal function that will return some value(primitive or an object) whereas creating service is like creating constructor function(OO class) of which we can create instance using new keyword. The only thing to notice is here is that when we use Service method to create services it will automatically create instance of it using dependency injection mechanism supported by AngularJS
Success story sharing
new
on it.