angular.service vs angular.factory angular.service vs angular.factory angularjs angularjs

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


Simply put ..

const user = {  firstName: 'john'};// Factoryconst addLastNameFactory = (user, lastName) => ({  ...user,  lastName,});console.log(addLastNameFactory(user, 'doe'));// Serviceconst addLastNameService = (user, lastName) => {  user.lastName = lastName; // BAD! Mutation  return user;};console.log(addLastNameService(user, 'doe'));