AngularJS : Factory and Service? [duplicate]
Asked Answered
B

4

222

EDIT Jan 2016: Since this still gets attention. Since asking this I've completed a few AngularJS projects, and for those I mostly used factory, built up an object and returned the object at the end. My statements below are still true, however.

EDIT : I think I finally understand the main difference between the two, and I have a code example to demonstrate. I also think this question is different to the proposed duplicate. The duplicate says that service is not instantiable, but if you set it up as I demonstrated below, it actually is. A service can be set up to be exactly the same as a factory. I will also provide code that shows where factory fails over service, which no other answer seems to do.

If I set up VaderService like so (ie as a service):

var module = angular.module('MyApp.services', []);

module.service('VaderService', function() {
    this.speak = function (name) {
        return 'Join the dark side ' + name;
    }
});

Then in my controller I can do this:

module.controller('StarWarsController', function($scope, VaderService) {
    $scope.luke = VaderService.speak('luke');   
});

With service, the VaderService injected in to the controller is instantiated, so I can just call VaderService.speak, however, if I change the VaderService to module.factory, the code in the controller will no longer work, and this is the main difference. With factory, the VaderService injected in to the controller is not instantiated, which is why you need to return an object when setting up a factory (see my example in the question).

However, you can set up a service in the exact same way as you can set up a factory (IE have it return an object) and the service behaves the exact same as a factory

Given this information, I see no reason to use factory over service, service can do everything factory can and more.

Original question below.


I know this has been asked loads of times, but I really cannot see any functional difference between factories and services. I had read this tutorial: http://blogs.clevertech.biz/startupblog/angularjs-factory-service-provider

And it seems to give a reasonably good explanation, however, I set up my app as follows:

index.html

<!DOCTYPE html>
<html>
    <head>
    <title>My App</title>
    <script src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="js/controllers.js"></script>
    <script type="text/javascript" src="js/VaderService.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
    </head>

    <body ng-app="MyApp"> 
        <table ng-controller="StarWarsController">
            <tbody>
            <tr><td>{{luke}}</td></tr>
            </tbody>
        </table>
    </body>
</html>

app.js:

angular.module('MyApp', [
  'MyApp.services',
  'MyApp.controllers'
]);

controllers.js:

var module = angular.module('MyApp.controllers', []);

module.controller('StarWarsController', function($scope, VaderService) {
    var luke = new VaderService('luke');
    $scope.luke = luke.speak();
});

VaderService.js

var module = angular.module('MyApp.services', []);

module.factory('VaderService', function() {
    var VaderClass = function(padawan) {
        this.name = padawan;
        this.speak = function () {
            return 'Join the dark side ' + this.name;
        }
    }

    return VaderClass;
});

Then when I load up index.html I see "Join the dark side luke", great. Exactly as expected. However if I change VaderService.js to this (note module.service instead of module.factory):

var module = angular.module('MyApp.services', []);

module.service('VaderService', function() {
    var VaderClass = function(padawan) {
        this.name = padawan;
        this.speak = function () {
            return 'Join the dark side ' + this.name;
        }
    }

    return VaderClass;
});

Then reload index.html (I made sure I emptied the cache and did a hard reload). It works exactly the same as it did with module.factory. So what is the real functional difference between the two??

Becalmed answered 15/4, 2014 at 4:47 Comment(2)
Here are some good answers about how services, factories and providers works.Shull
Your edited part makes more sense than any other answer over here :)Obadiah
P
301

Service vs Factory


enter image description here enter image description here

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?

Poeticize answered 15/4, 2014 at 6:24 Comment(5)
This makes sense to me now! So I could conceivably make a service behave like a factory, but that kind of goes against what services are designed to be used for. Further, if I don't return anything when I use module.factory, things won't work properly, correct?Becalmed
Is it just me or does it seem like a service is kinda pointless?Lawry
The last link is not valid anymore.Alcus
I dont like the factory example, as its identical to service (altough valid). Factories can return functions, but the conceptual difference between the two should be about variables - services are like class (New = empty object) and factories like object (= static data/values).Cavorilievo
So as someone that is using a "service" to communicate between two controllers for updating a single variable that effects two separate controllers, a service is the right way to go?Alica
T
46

Factory and Service is a just wrapper of a provider.

Factory

Factory can return anything which can be a class(constructor function), instance of class, string, number or boolean. If you return a constructor function, you can instantiate in your controller.

 myApp.factory('myFactory', function () {

  // any logic here..

  // Return any thing. Here it is object
  return {
    name: 'Joe'
  }
}

Service

Service does not need to return anything. But you have to assign everything in this variable. Because service will create instance by default and use that as a base object.

myApp.service('myService', function () {

  // any logic here..

  this.name = 'Joe';
}

Actual angularjs code behind the service

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
        return $injector.instantiate(constructor);
    }]);
}

It just a wrapper around the factory. If you return something from service, then it will behave like Factory.

IMPORTANT: The return result from Factory and Service will be cache and same will be returned for all controllers.

When should i use them?

Factory is mostly preferable in all cases. It can be used when you have constructor function which needs to be instantiated in different controllers.

Service is a kind of Singleton Object. The Object return from Service will be same for all controller. It can be used when you want to have single object for entire application. Eg: Authenticated user details.

For further understanding, read

http://iffycan.blogspot.in/2013/05/angular-service-or-factory.html

http://viralpatel.net/blogs/angularjs-service-factory-tutorial/

Tal answered 15/4, 2014 at 4:56 Comment(11)
Why would you choose one over the other, then? And can you give me a solid example of something factory can do that service cannot? I still don't really understand the difference.Becalmed
Updated the answer for when you need to use them.Tal
I see your edit, but if you look at the example I provided, I can instantiate a service in exactly the same way I would do it with a factory, so what is factory giving me that service does not?Becalmed
Yes you are correct. Service is simple wrapper which creates simple object and call the service function where you have to use this object. Incase if you return anything, then it will take return result and not this object. Then it behave like Factory.Tal
But then why does factory exist?? I really don't understand why there are two features that seemingly do the same thing! What I really want is a concrete example of something that can be done with factory and cannot be done with service (or the other way around).Becalmed
As i said, Factory can be used for all cases. I always use Factory. I added the actual code behind service in the answers. It just uses Factory, but it creates new object and pass it factory function. Thats it. You can achieve everything by Factory.Tal
Since a Factory lets you return the object, you have control over what is exposed, meaning you can kind of have private methods in factories. With services, the entire object is exposed.Afton
@eet, In service also we can have private method. Whatever you assign to this object will be exposed. Other functions are private. Service just reduce to create object yourself.Tal
I disagree that factory can be used for everything. Look at the edit in my question and you will see that service actually can do everything factory can do and more.Becalmed
Service and factory both are singleton.Cockup
Good explanation!Cannibalism
M
7
  • 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)

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.

Reference

Manatarms answered 15/4, 2014 at 4:53 Comment(1)
I don't really understand what that means. Can you give me an example that shows something you can do with a factory but not with a service, or vica versa?Becalmed
E
4

$provide service

They are technically the same thing, it's actually a different notation of using the provider function of the $provide service.

  • If you're using a class: you could use the service notation.
  • If you're using an object: you could use the factory notation.

The only difference between the service and the factory notation is that the service is new-ed and the factory is not. But for everything else they both look, smell and behave the same. Again, it's just a shorthand for the $provide.provider function.

// Factory

angular.module('myApp').factory('myFactory', function() {

  var _myPrivateValue = 123;

  return {
    privateValue: function() { return _myPrivateValue; }
  };

});

// Service

function MyService() {
  this._myPrivateValue = 123;
}

MyService.prototype.privateValue = function() {
  return this._myPrivateValue;
};

angular.module('myApp').service('MyService', MyService);
Evers answered 15/4, 2014 at 5:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.