2

I'm learning AngluarJS and I have a very simple project set up.

I have a file called ApiService.js which is used to pull data from a RESTful server somewhere. At the moment it looks like this:

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

module.service('ApiService', function() {
    this.getDataList = function() {
       ...
       ...
    }
});

Then I have a controller that uses it like this:

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

module.controller('dataController', function($scope, ApiService) {
    $scope.dataList = ApiService.getDataList();
});

I'm unsure if I should be using module.service or module.factory in my services.js (it also confuses me that the convention is to call the file services.js when factories can be in there). I know what a factory is and I know what a service is in regular software design patterns, but I don't know what I should be doing to do this the Angular way.

What is correct, service or factory?

Cameron Ball
  • 4,048
  • 6
  • 25
  • 34
  • Check out this post for a good explanation of factories, services and providers in AngularJS: http://stackoverflow.com/questions/15666048/angular-js-service-vs-provider-vs-factory – link64 Apr 15 '14 at 03:18
  • The differences are so subtle; I don't think it matters. When I Started I used factories, but have moved onto services. – JeffryHouser Apr 15 '14 at 03:18
  • I've read that question, but I'm still not really sure. I feel like I should be using a service as the dataApi should be the same everywhere in my application. A factory will make a new instance every time. – Cameron Ball Apr 15 '14 at 03:23
  • @CameronBall A Factory will not make a new instance every time. I elaborated on this in a formal answer; because I thought you may be going through some of the same 'confusion' I originally did. – JeffryHouser Apr 15 '14 at 03:31

1 Answers1

1

I thought I'd elaborate a bit in a real answer. I believe the differences between a service and a factory are so subtle it doesn't really matter.

However, you stated that you know what a factory is and what a service is in design patterns. I thought I would elaborate on that a bit because I think that factory and service--as applied to AngularJS--are a bit misleading.

First, the Factory design pattern is, basically, an object that creates other objects. However, when you create a factory in AngularJS; you do not use that factory to create other objects. The object returned from an Angular Factory is a Singleton and only one object will ever be returned when you access that factory. So, an Angular factory does not have the same meaning as "Factory" that I have used in the passed. In fact, when you create an Angular factory, you are responsible for creating the object, within the factory function. Once the object is created, the same object is always returned. So an Angular Factory does not even create a new object even once. It is nothing like a factory as I understood them from other languages.

A Service design pattern is really just a fancy way to organize different functionality so that it is separate from them. Back when I Was in school we just called this 'encapsulation' and I don't think of it as a design pattern. Both the AngularJS Service and the AngularJS Factory can you help you do this.

The Angular Service is also a singleton, but the first time that service is referenced, it will call 'new' on the object in question. That means that the service creates a new object--so the AngularJS Service is more like a Factory than the AngularJS Factory. An Angular service is still a singleton, so once the object is created, the same object will always be returned.

For all practical purposes, I use a service. They seem to be easier to set up. But the differences appear to be very subtle.


Okay, let's add some elaboration on how factories and services work.

Say, you have en object created like this:

MyObject - function MyObject(){
 foo : "bar";
}

This object exists outside of AngularJS and could be used in any JavaScript. If you want to use it with a factory; you would do something like this:

MyApp.factory('MyObjectFactory', function(){
    return new MyObject();
});

Notice I had to manually call the new MyObject() fucntion to create a new object in the factory function. I could have also returned an existing object, like this:

MyApp.factory('MyObjectFactory', function(){
    return MyObject;
});

Now, you want to pass it into a controller like this:

function MyController($scope, MyObjectFactory) {}

Angular finds the argument into the controller and looks for MyObjectFactory. It if it not yet instantiated, then the factory function is called, and the results are returned. The results are cached, so every time Angular needs to reference MyObjectFactory it will return the same object that was created the first time. The returned object in a Singleton and this is how you can share the same object between different controllers.

The key point here is that the factory function is executed once; on first access of the factory. It is not used to manage the creation of multiple objects of the same type.

A service out of the same object may be created like this:

MyApp.service('MyObjectService', MyObject);

And passed into the same controller, like this:

function MyController($scope, MyObjectFactory, MyObjectService) {}

When Angular needs to reference the MyObjectService for the first time, it will execute "new MyObject()" and return that object. The object is cached and every time MyObjectService is needed, the same object is returned.

After this creation process, it is identical in usage to an AngularJS Factory. It is a singleton object, and you can use it to share data, or functionality between controllers.

So, in the short, when using a Service a new instance of your object is automatically created. When using a Factory, whatever object is returned from your factory function is returned.

Under the hood, both Service and Factory use a provider. With a service the factory function is provided for you. With a factory, you can make the function anything you want.

JeffryHouser
  • 39,401
  • 4
  • 38
  • 59
  • Angular factory is a simple javascript function that is responsible to create and object and return. This function only gets called once during the lifetime of app, and the results reused everywhere. I am not sure your definition of Factory is correct. `In fact, when you create an Angular factory, you pass the object into it and that object is always returned. So an Angular Factory does not even create a new object even once. It is nothing like a factory as I understood them from other languages.` – Chandermani Apr 15 '14 at 03:51
  • @Chandermani With an AngularJS Factory; a new object is not created. The 'new' function is called with an AngularJS service, but not with a factory. With a factory it is up to you to call the 'new' function, therefore the factory does not create a new object at all. See this in depth description for more info: http://stackoverflow.com/questions/15666048/angular-js-service-vs-provider-vs-factory – JeffryHouser Apr 15 '14 at 04:30
  • I was talking about the object that you return from the factory function using `return someObj`, Yes factory function is just a javascript function. – Chandermani Apr 15 '14 at 04:42
  • @Chandermani I updated my question to elaborate more w/ samples. Maybe I'm intercommunicating; but you haven't said anything to make me think I an incorrect yet. The original poster made the same mistake I originally did--assumed that a factory will create a new object every time because that is what factories are usually used for in my other development experience. The AngularJS Factory does not operate that way. – JeffryHouser Apr 15 '14 at 04:50
  • @Chandermani and I re-worked the text you pointed out; because you're right it was misleading. A function is passed into an AngularJS Factory; not a generic object instance. – JeffryHouser Apr 15 '14 at 04:57
  • I asked this question in a different way here http://stackoverflow.com/questions/23074875/difference-between-factory-and-service-in-angularjs/23076054?noredirect=1#23076054 my conclusion is that service is the better choice as you can make it behave like factory if you want. – Cameron Ball Apr 16 '14 at 07:19