0

This answer (and numerous others) point out that .factory and .service are distinct convenience functions over the provider() functionality.

However, I don't see any distinction between a .service() and a .factory() call (ie: the tests below pass). Can someone help me understand what I'm missing. thanks

angular.module('myMod', [])
  .service('myService', function() {
    return function() {return 33};
  })
  .factory('myFactory', function() {
    return function() {return 33};
  });

describe('my app tests', function() {

  beforeEach(module('myMod'));

  it('services should work', inject(function(myService) {
    expect(myService()).to.equal(33);
  }));

  it('factories should work', inject(function(myFactory) {
    expect(myFactory()).to.equal(33);
  }));

});
Community
  • 1
  • 1
RoyM
  • 1,118
  • 1
  • 9
  • 28
  • 1
    It seems that you can either return a factory function, or a new-able function.. but what I'm trying to get at is: there doesn't seem to be any real difference between how a .service() call works, vs a .factory() call. – RoyM Mar 09 '15 at 20:56
  • agreed. I'll remove the close vote – New Dev Mar 09 '15 at 22:49
  • on another note, an extreme take on this issue: http://codeofrob.com/entries/you-have-ruined-javascript.html – RoyM Mar 10 '15 at 17:43
  • This blogger seem to have misunderstood the use of `.service`, `.factory`, and `.provider`. It's one or the other, not all of them. – New Dev Mar 10 '15 at 19:03

1 Answers1

2

.factory is used to register a function that returns an instance of an object that will be the injected service singleton.

.service is used to register a function that will be used as constructor of an object that will be the injected service singleton.

.service actually uses .factory under the covers. From src:

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

In other words, .service registers a factory function that calls $injector.instantiate on the function (called constructor above) that is registered with .service.

Now, to your case, the function you register is:

var fn = function(){ return function(){ return 13; }; }

fn just returns an object (which happens to be another function).

In .factory case, fn is invoked directly: var svc = fn();

In .service case, fn is called like a constructor, but ends up not setting anything on this and returning an object (constructors can return a different instance than this) - same function object as above. So, var svc = $injector.instantiate(fn).

In both cases, svc equals to a function object: function(){ return 13; }

New Dev
  • 48,427
  • 12
  • 87
  • 129
  • Here is my understanding this far: * You can inject a service in many places; each is the same instance. A service is not parameterizable. * A factory is parameterizable, and designed to create multiple instances; Controller providers are examples of a factory. You have to use new X() when using a factory. – RoyM Mar 10 '15 at 17:37