Angularjs:Factory and Service

AngularJS : Factory and Service?

Service vs Factory


Sample Image
Sample Image

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);

Service Provider

  • 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 keyword

  • Dependencies 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);

Sample Demo

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 .factory


module.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 factory

provide.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 write

provide.factory('greeter', function(a) {
return new Greeter(a);
});

Then we could ask for 'greeter' in controller like this

function 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).

ref: angular.service vs angular.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 ?

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."

(ref: http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821).


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

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

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


Sample Image

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);

Service Provider

  • 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);

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() {
//..
return functionValue;
}

this.method2 = function() {
//..
return functionValue;
}
});

AngularJS .factory


module.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



Leave a reply



Submit