61723

AngularJS : When to use service instead of factory

Question:

<blockquote>

Please bear with me here. I know there are other answers such as: <a href="https://stackoverflow.com/questions/15666048/angular-js-service-vs-provider-vs-factory" rel="nofollow">AngularJS: Service vs provider vs factory</a>

</blockquote>

<strong>However I still can't figure out when you'd use service over factory.</strong>

From what I can tell factory is commonly used to create "common" functions that can be called by multiple Controllers: <a href="https://stackoverflow.com/questions/11324202/angularjs-common-controller-functions?lq=1" rel="nofollow">Creating common controller functions</a>

The Angular docs seem to prefer factory over service. They even refer to "service" when they use factory which is even more confusing! <a href="http://docs.angularjs.org/guide/dev_guide.services.creating_services" rel="nofollow">http://docs.angularjs.org/guide/dev_guide.services.creating_services</a>

<strong>So when would one use service?</strong>

Is there something that is only possible or much easier done with service?

Is there anything different that goes on behind the scenes? Performance/memory differences?

Here's an example. Other than the method of declaration, they seem identical and I can't figure out why I'd do one vs the other. <a href="http://jsfiddle.net/uEpkE/" rel="nofollow">http://jsfiddle.net/uEpkE/</a>

<strong>Update:</strong> From Thomas' answer it seems to imply that service is for simpler logic and factory for more complex logic with private methods, so I updated the fiddle code below and it seems that both are able to support private functions?

myApp.factory('fooFactory', function() { var fooVar; var addHi = function(foo){ fooVar = 'Hi '+foo; } return { setFoobar: function(foo){ addHi(foo); }, getFoobar:function(){ return fooVar; } }; }); myApp.service('fooService', function() { var fooVar; var addHi = function(foo){ fooVar = 'Hi '+foo;} this.setFoobar = function(foo){ addHi(foo); } this.getFoobar = function(){ return fooVar; } }); function MyCtrl($scope, fooService, fooFactory) { fooFactory.setFoobar("fooFactory"); fooService.setFoobar("fooService"); //foobars = "Hi fooFactory, Hi fooService" $scope.foobars = [ fooFactory.getFoobar(), fooService.getFoobar() ]; }

Answer1:

<h2>Explanation</h2>

You got different things here:

<strong>First:</strong>

<ul><li>If you use a service you will get <strong>the instance of a function</strong> ("this" keyword). </li> <li>If you use a factory you will get <strong>the value that is returned by invoking the function reference</strong> (the return statement in factory).</li> </ul>

<em>ref:</em> <a href="https://stackoverflow.com/questions/14324451/angular-service-vs-angular-factory" rel="nofollow">angular.service vs angular.factory</a>

<strong>Second:</strong>

Keep in mind all providers in AngularJS (value, constant, services, factories) are singletons!

<strong>Third:</strong>

Using one or the other (service or factory) is about code style. But, the <strong>common way</strong> in AngularJS is to use <strong>factory</strong>.

Why ?

<blockquote>

<strong>Because</strong> <em>"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."</em>

</blockquote>

(<em>ref</em>: <a href="http://rads.stackoverflow.com/amzn/click/1782161821" rel="nofollow">http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821</a>).

<hr /><h2>Usage</h2>

<em>Service :</em> 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.

<em>Factory :</em> Could be useful for returning a ‘class’ function that can then be new`ed to create instances.

So, <strong>use a factory when you have complex logic</strong> in your service and <strong>you don't want expose this complexity</strong>.

In other cases <strong>if you want to return an instance of a service just use service</strong>.

But you'll see with time that you'll use factory in 80% of cases I think.

For more details: <a href="http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/" rel="nofollow">http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/</a>

<hr />

<strong>UPDATE :</strong>

Excellent post here : <a href="http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html" rel="nofollow">http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html</a>

<blockquote>

"If you want your function <strong>to be called like a normal function</strong>, use <strong><em>factory</em></strong>. If you want your function to be instantiated with the new operator, use service. If you don't know the difference, use factory."

</blockquote> <hr />

<strong>UPDATE :</strong>

AngularJS team does his work and give an explanation: <a href="http://docs.angularjs.org/guide/providers" rel="nofollow">http://docs.angularjs.org/guide/providers</a>

And from this page :

<blockquote>

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

</blockquote>

Answer2:

<a href="https://stackoverflow.com/users/454252/allenhwkim" rel="nofollow">allernhwkim</a> originally posted <a href="https://stackoverflow.com/questions/18939709/when-to-use-service-instead-of-factory#20614250" rel="nofollow">an answer</a> on this question linking to <a href="http://allenhwkim.tumblr.com/post/69895172775/service-factory-and-provider-whats-difference" rel="nofollow">his blog</a>, however a moderator deleted it. It's the only post I've found which doesn't just tell you how to do the same thing with service, provider and factory, but also tells you what you can do with a provider that you can't with a factory, and with a factory that you can't with a service.

Directly from his blog:

app.service('CarService', function() { this.dealer="Bad"; this.numCylinder = 4; }); app.factory('CarFactory', function() { return function(numCylinder) { this.dealer="Bad"; this.numCylinder = numCylinder }; }); app.provider('CarProvider', function() { this.dealerName = 'Bad'; this.$get = function() { return function(numCylinder) { this.numCylinder = numCylinder; this.dealer = this.dealerName; } }; this.setDealerName = function(str) { this.dealerName = str; } });

This shows how the CarService will always a produce a car with 4 cylinders, you can't change it for individual cars. Whereas CarFactory returns a function so you can do new CarFactory in your controller, passing in a number of cylinders specific to that car. You can't do new CarService because CarService is an object not a function.

The reason factories don't work like this:

app.factory('CarFactory', function(numCylinder) { this.dealer="Bad"; this.numCylinder = numCylinder });

And automatically return a function for you to instantiate, is because then you can't do this (add things to the prototype/etc):

app.factory('CarFactory', function() { function Car(numCylinder) { this.dealer="Bad"; this.numCylinder = numCylinder }; Car.prototype.breakCylinder = function() { this.numCylinder -= 1; }; return Car; });

See how it is literally a factory producing a car.

The conclusion from his blog is pretty good:

<blockquote>

In conclusion,

--------------------------------------------------- | Provider| Singleton| Instantiable | Configurable| --------------------------------------------------- | Factory | Yes | Yes | No | --------------------------------------------------- | Service | Yes | No | No | --------------------------------------------------- | Provider| Yes | Yes | Yes | --------------------------------------------------- <ol><li>

Use Service when you need just a simple object such as a Hash, for example {foo;1, bar:2} It’s easy to code, but you cannot instantiate it.

</li> <li>

Use Factory when you need to instantiate an object, i.e new Customer(), new Comment(), etc.

</li> <li>

Use Provider when you need to configure it. i.e. test url, QA url, production url.

</li> </ol></blockquote>

If you find you're just returning an object in factory you should probably use service.

Don't do this:

app.factory('CarFactory', function() { return { numCylinder: 4 }; });

Use service instead:

app.service('CarService', function() { this.numCylinder = 4; });

Answer3:

The concept for all these providers is much simpler than it initially appears. If you dissect a provider you and pull out the different parts it becomes very clear.

To put it simply each one of these providers is a specialized version of the other, in this order: provider > factory > value / constant / service.

So long the provider does what you can you can use the provider further down the chain which would result in writing less code. If it doesn't accomplish what you want you can go up the chain and you'll just have to write more code.

This image illustrates what I mean, in this image you will see the code for a provider, with the portions highlighted showing you which portions of the provider could be used to create a factory, value, etc instead.

<a href="http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/" rel="nofollow">AngularJS providers, factories, services, etc are all the same thing http://www.simplygoodcode.com/wp-content/uploads/2015/11/angularjs-provider-service-factory-highlight.png</a>

For more details and examples from the blog post where I got the image from go to: <a href="http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/" rel="nofollow">http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/</a>

Answer4:

Both the factory and the service result in singleton objects which are able to be configured by providers and injected into controllers and run blocks. From the point of view of the injectee, there is absolutely no difference whether the object came from a factory or a service.

So, when to use a factory, and when to use a service? It boils down to your coding preference, and nothing else. If you like the modular JS pattern then go for the factory. If you like the constructor function ("class") style then go for the service. Note that both styles support private members.

The advantage of the service might be that it's more intuitive from the OOP point of view: create a "class", and, in conjunction with a provider, reuse the same code across modules, and vary the behavior of the instantiated objects simply by supplying different parameters to the constructor in a config block.

Answer5:

There is nothing a Factory cannot do or does better in comparison with a Service. And vice verse. Factory just seems to be more popular. The reason for that is its convenience in handling private/public members. Service would be more clumsy in this regard. When coding a Service you tend to make your object members public via “this” keyword and may suddenly find out that those public members are not visible to private methods (ie inner functions).

var Service = function(){ //public this.age = 13; //private function getAge(){ return this.age; //private does not see public } console.log("age: " + getAge()); }; var s = new Service(); //prints 'age: undefined'

Angular uses the “new” keyword to create a service for you, so the instance Angular passes to the controller will have the same drawback. Of course you may overcome the problem by using this/that:

var Service = function(){ var that = this; //public this.age = 13; //private function getAge(){ return that.age; } console.log("age: " + getAge()); }; var s = new Service();// prints 'age: 13'

But with a large Service constant this\that-ing would make the code poorly readable. Moreover, the Service prototypes will not see private members – only public will be available to them:

var Service = function(){ var name = "George"; }; Service.prototype.getName = function(){ return this.name; //will not see a private member }; var s = new Service(); console.log("name: " + s.getName());//prints 'name: undefined'

Summing it up, using Factory is more convenient. As Factory does not have these drawbacks. I would recommend using it by default.

Answer6:

Even when they say that all services and factories are singleton, I don't agree 100 percent with that. I would say that factories are not singletons and this is the point of my answer. I would really think about the name that defines every component(Service/Factory), I mean:

A <strong>factory</strong> because is not a singleton, you can create as many as you want when you inject, so it works like a factory of objects. You can create a factory of an entity of your domain and work more comfortably with this objects which could be like an object of your model. When you retrieve several objects you can map them in this objects and it can act kind of another layer between the DDBB and the AngularJs model.You can add methods to the objects so you oriented to objects a little bit more your AngularJs App.

Meanwhile a <strong>service</strong> is a singleton, so we can only create 1 of a kind, maybe not create but we have only 1 instance when we inject in a controller, so a service provides more like a common service(rest calls,functionality.. ) to the controllers.

Conceptually you can think like services provide a service, factories can create multiple instances(objects) of a class

Answer7:

<strong>Services</strong>

<strong>Syntax</strong>: module.service( 'serviceName', function ); <strong>Result</strong>: When declaring serviceName as an injectable argument you will be provided the actual function reference passed to module.service.

<strong>Usage</strong>: 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.

<strong>Factories</strong>

<strong>Syntax</strong>: module.factory( 'factoryName', function );

<strong>Result</strong>: When declaring factoryName as an injectable argument you will be provided the value that is returned by invoking the function reference passed to module.factory.

<strong>Usage</strong>: Could be useful for returning a 'class' function that can then be new'ed to create instances.

<strong>Providers</strong>

<strong>Syntax</strong>: module.provider( 'providerName', function );

<strong>Result</strong>: When declaring providerName as an injectable argument you will be provided the value that is returned by invoking the $get method of the function reference passed to module.provider.

<strong>Usage</strong>: Could be useful for returning a 'class' function that can then be new'ed to create instances but that requires some sort of configuration before being injected. Perhaps useful for classes that are reusable across projects? Still kind of hazy on this one.

Answer8:

Can use both <strong>the way you want</strong> : whether <strong>create object</strong> or j<strong>ust to access functions</strong> from both

<hr /><blockquote>

<strong>You can create new object from service</strong>

</blockquote> app.service('carservice', function() { this.model = function(){ this.name = Math.random(22222); this.price = 1000; this.colour = 'green'; this.manufacturer = 'bmw'; } }); .controller('carcontroller', function ($scope,carservice) { $scope = new carservice.model(); })

Note :

<ul><li>service by default returns object and not constructor function .</li> <li>So that's why constructor function is set to this.model property.</li> <li>Due to this service will return object,but but but inside that object will be constructor function which will be use to create new object;</li> </ul><blockquote>

<strong>You can create new object from factory</strong>

</blockquote> app.factory('carfactory', function() { var model = function(){ this.name = Math.random(22222); this.price = 1000; this.colour = 'green'; this.manufacturer = 'bmw'; } return model; }); .controller('carcontroller', function ($scope,carfactory) { $scope = new carfactory(); })

Note :

<ul><li>factory by default returns constructor function and not object .</li> <li>So that's why new object can be created with constructor function.</li> </ul><blockquote>

<strong>Create service for just accessing simple functions</strong>

</blockquote> app.service('carservice', function () { this.createCar = function () { console.log('createCar'); }; this.deleteCar = function () { console.log('deleteCar'); }; }); .controller('MyService', function ($scope,carservice) { carservice.createCar() }) <blockquote>

<strong>Create factory for just accessing simple functions</strong>

</blockquote> app.factory('carfactory', function () { var obj = {} obj.createCar = function () { console.log('createCar'); }; obj.deleteCar = function () { console.log('deleteCar'); }; }); .controller('MyService', function ($scope,carfactory) { carfactory.createCar() })

Conclusion :

<ul><li>you can use both <strong>the way you want</strong> whether to create new object or just to access simple functions</li> <li>There won't be any performance hit , using one over the other</li> <li>Both are singleton objects and only one instance is created per app.</li> <li>Being only one instance every where their reference is passed.</li> <li>In angular documentation <strong>factory is called service</strong> and also <strong>service is called service</strong>.</li> </ul>

Recommend

  • Time Complexity of operation - Python
  • Need explanation for algorithm searching minimal large sum
  • Index-based fetching of Objective-C argument values
  • Pandas ordered categorical data on exam grades 'D',…,'A+'
  • JavaScript: modify prototype of an object's variable?
  • disadvantages of marquee tag [closed]
  • SSH, run process and then ignore the output
  • Dynamic Programming - top-down vs bottom-up
  • What are the best practices for migrating an Oracle 10g database to Microsoft SQL 2008 R2? Applicati
  • Time Complexity of the given nested loops
  • Insert a multiline string with arbitrary special characters to a template file in a shell script
  • Dynamic programming matrix chain multiplication
  • Select Earliest Order for a set of tests in a daterange SQL
  • Entity Framework Code First Circular Dependices
  • Why the time complexity of an array insertion is O(n) and not O(n+1)? [duplicate]
  • How to debug problems with the javafx native bundle for Windows?
  • LNK1104: cannot open file 'kernel32.lib'
  • Invert string in Rust
  • crash in __tcf_0
  • Less Conflicting Session Manager for Zope 2
  • For loop with if condition on multiple R functions
  • calculate gradient output for Theta update rule
  • Loading .coffee files via a view in Rails
  • Content-Length header not returned from Pylons response
  • NHibernate Validation Localization with S#arp Architecture
  • Does CUDA 5 support STL or THRUST inside the device code?
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • retrieve vertices with no linked edge in arangodb
  • PHP: When would you need the self:: keyword?
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • Understanding cpu registers
  • Java static initializers and reflection
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • How can I remove ASP.NET Designer.cs files?
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • Add sale price programmatically to product variations
  • unknown Exception android
  • JaxB to read class hierarchy
  • Observable and ngFor in Angular 2
  • Unable to use reactive element in my shiny app