7 ms·
AngularJS: Factory vs. Service vs. Provider
- chao- 12y agoI enjoy quite a few parts of Angular, but its choice of naming between Factories & Services is maddening. The fact that Factories are not Factories-as-seen-in-any-other-context made me sad. Unless I am mistaken, from what I have seen: Angular Factories are Singletons (you always get the same object). Angular Services are Factories (you can get many independent instances of an object from them).
- spion 12y agoNope, they're all singletons. While providers may be useful, the distinction between service and factory is completely useless (service is completely unnecessary :) At this point the angular team should probably just deprecate module.service and remove it from the docs to avoid causing this massive confusion.
- jonny_eh 12y agoWhy not the other way around? You can use .service as you would a .factory, and it makes sense that .service is used to create services just like .controller creates controllers.
- spion 12y agoBecause .factory is slightly more general (can return non-objects), and it can't be called .service because backward compatibility.
- jonny_eh 12y agoThe article seems to be down for me. Can you give an example of a case where a .service won't cut it but a . Factory would?
- minznerjosh 12y ago.factory('$timeout', function($window) { var $timeout = $window.setTimeout; return $timeout; }) .service('$timeout', function($window) { // $timeout is a function, not an normal object. Why would I use a constructor //function to provide it? });
- alttab 12y agoI want the bike shed to be blue, god dammit!
- jacques_chester 12y agoBonus points round: Scopes are the actual Controllers, after instantiation. Controllers are actually Factories that annotate Scopes until you have the instance. $controller() is ... I don't even know any more.
- minznerjosh 12y agoI don't know if I'd say Scopes are controllers after the controllers are instantiated. Scopes are more of a view-model which are, yes, annotated by Controllers. However, if you put your Controllers on the Scope (via $scope.MyCtrl = this; in the constructor, or via the controllerAs syntax), your controllers are your controllers, placed on the view-model (the scope.) But this is really just semantics at this point. I totally get what you're saying.
- badman_ting 12y agoI can see why we need providers, and either services or factories, but not both. I prefer not to use 'this' in JS where possible, so factory it is.
- minznerjosh 12y agoReally, Services and Factories are just a shorthand way of creating providers. .factory('foo', function() { var foo = {}; return foo; }); is the same as: .provider('foo', function() { this.$get = function() { var foo = {}; return foo; }; }); And, .service('foo', function() { this.bar = 'bar'; }); is the same as: .factory('foo', function() { function Foo() { this.bar = 'bar'; } return new Foo(); }); is the same as: .provider('foo', function() { this.$get = function() { function Foo() { this.bar = 'bar'; } return new Foo(); } });
- acoyfellow 12y agoSo when should we use each?
- minznerjosh 12y agoThat can be a matter of personal preference, so the best I can do is share my preference. I usually use the "service" method because most of my services are objects, and I have no aversion to constructor functions. However, if I want my service to be a function (a la $http or $timeout,) I'll use a factory (because I don't want a constructor to be new-ed, I just want to create a function.) And, as the article states, I'd use a provider if I want to provide methods to configure my service before it is instantiated. I think a lot of it comes down to semantics. Maybe it's just me, but describing my object via a constructor function (as a "service") makes it feel a bit weightier than creating and returning a POJO in a factory. But, from a practical standpoint, you can see it as this: A provider is responsible for creating (providing) an injectable (as a singleton) object that others can request to be injected. The provider creates this object in its $get method. It can also have methods/properties other than $get that can be called/modified in the config stage to configure the object it will create. But, often times (maybe the majority of times,) you don't need to configure your injectable before it is created, so we really only care about the $get method of the provider. This is where the "factory" API comes in. It just eliminates all the boilerplate around creating a provider that only has a $get method. And finally, for reasons that are not entirely clear to me, the angular team also decided to provide a shorthand for creating a constructor, and returning a new instance of that constructor in the $get method of the provider (or the factory function if you like.) And that's what the "service" API is. So, the provider is the root API, factory is sugar on top of the provider API, and service is sugar on top of factory API.
- bryan_rasmussen 12y agoFinally I feel like I understand Java. Was that too snarky?
- carsongross 12y agoExactly. How did we end up porting J2EE to the client side? People appear to think this is a good idea because... javascript? Because google? It's crazy. http://intercoolerjs.org/why.html http://intercoolerjs.org/why.html
- deleted 12y ago[deleted]
- alttab 12y agoI was reading through this and thinking "holy crap these angularJS guys are missing the entire point." They are running a damn app-server inside the browser page, for the love of god!
- fineline 12y agoWell, I'm missing it - what exactly is "the point"? When building client side applications that have hundreds of components and must be able to function in a stand-alone mode robustly, potentially over multiple user sessions, until a network connection becomes available, having access to a robust implementation of proven, testable software development patterns makes sense to me. It did when I was building those client-side apps in Java or .NET, what changes now I am building them in the language with wider reach than any other in history? All of a sudden I should approach it like a script kiddy?
- alttab 12y agoBuilding a client side application that has hundreds of components and be able to function in a stand-alone mode robustly, potentially over multiple user sessions, until a network connection becomes available, having access to a robust implementation of proven, testable software development patterns: - Objective C - Java + Android - Monad and #C Why are we killing ourselves with browsers? I mean, to a degree I get the cross platform deal... but unless you are building for exactly that environment (ie NOT A WEB APPLICATION) then it doesn't make sense to me... at all. There are better tools.
- cabbeer 12y agoI don't know if Angular is stupid or I am.
- catshirt 12y agowell said. Backbone has suited me very well over the past 3 years, and now React. i have a hard time understanding what necessitates all these patterns in the first place and how i've been able to write web applications without them.
- carsongross 12y agoI feel like there is variation on a Santayana quote I (think I) once read here: The world will never know what software monstrosities have been perpetrated for fear of appearing insufficiently smart.
- thenerdfiles 12y agoIt's when Angular has to play with something else, some other library or plugin. And the more Angular Modules you outsource, the hope is that you're all using Directives and Promises rigorously. It gives templates a lot more say in terms of complexity. Some days my vim looks like (mostly Directives): ---------------------------- | | | | | | | | | |-----------| | | | | | | | | | |-----------| | | | | | | ---------------------------- And I'm thinking: Oh god what's happening, is this the abyss?
- joevandyk 12y agoYou can put more than one directive in a file. If it gets too unweildy, separate stuff into separate files based on functionality (ordering.js, login.js, shared_ui.js, etc)
- olalonde 12y agoWhat I like about Angular: the scope system, two way binding, clever use of HTML markup for templating. I just wish it was more library like and less like a framework. I guess what I would really like to see is a hybrid of Backbone and Angular. Does such a thing exist?
- catshirt 12y agoi think i'd call Angular's use of HTML markup unfortunate before i'd call it clever. it's a side effect of mapping a view represented by a markup language (HTML) to the same view represented by a programming language (JS). i find React's implementation more clever, by giving you a single environment (JS) to declare your view's template and logic.
- zoomerang 12y agoI love Angular for exactly that reason. My HTML template should be a HTML file. I cannot stand codebases that mix code and markup together.
- hcarvalhoalves 12y agoIf that's a stab at React.js, notice nothing stops you from having the JSX markup on a separate file. You can also convert from plain HTML to JSX. [1] [1] http://facebook.github.io/react/html-jsx.html http://facebook.github.io/react/html-jsx.html
- zoomerang 12y agoMore a distaste with the design pattern of mixing HTML and Logic in one monolithic codebase. (i.e. lack of proper separation of concerns) Forcing a clear separation leads Junior developers towards a better design, which is one of the reasons I like Angular - I can put a junior dev on a project and have them productive within about 10 minutes while feeling fairly confident they will do things the right way. It's a very easy framework to get started with, leads you towards a good overall architecture, and is deep/powerful enough that it doesn't fall over when things get hairy 85,000 lines of code later. Obviously good React code will keep proper separation of concerns (whether using standalone templates or not), but I do worry a lot of developers will cheat and start emitting snippets of HTML in areas of the codebase that shouldn't be doing that. Mind you React.js is a great framework, I just personally prefer Angular based on experience working with both.
- Geee 12y agoYesterday, I spent 8 hours writing an AngularJS directive for setting focus on an input field. You know, last year we used to just document.getElementById('myfield').focus(), but it's much more reusable and maintainable with a custom 'focusable' directive. If you want to learn more about the subject: http://stackoverflow.com/questions/14833326/how-to-set-focus-in-angularjs http://stackoverflow.com/questions/14833326/how-to-set-focus...
- camus2 12y agoSome stuffs are definetly difficult to do,but the advantages outweight the disavantages in most cases.
- carsongross 12y agomuch more reusable and maintainable <sarc/>?
- zoomerang 12y agoIf you can solve something in jQuery, why are you using Angular? Wrong tool for the job. If you have an application that otherwise uses Angular, and you have a snippet of jQuery code that you want to use, wrapping it in a directive takes about 30 seconds. Alternatively, if you don't want to write a directive, you can just run the jQuery code directly as if Angular didn't even exist.
- collyw 12y agoBecause the cool kids are all using Angular and NoSQL.
- camus2 12y agothe guy didnt want to name them singelton (because it is what hey are basically), because of bad rep,so he went with factory/service/provider. It's like naming your presenter controllers when they are not controllers. Angular definetly has a nomenclature problem which make it difficult to understand at first, but its concepts are quite simple and elegant.
- IgorPartola 12y agoAngular reminds me of Puppet in an odd way. Reading the Puppet docs you will come across passages that say "in the recent release we have added this new feature. Do not use it as it is not well thought through and here is the old simple reliable way to get what you want done." Angular seems to suffer from the same problem. Services are completely unnecessary as Factories are a far simpler and superior way of doing things. Providers are a terrible way to do things. Instead a config service (with a lowercase s) should handle getting initial values to the Factory. The DI system that works in dev but not prod unless you use the explicit way of listing your dependencies is another example of this.