AngularJS: Factory vs. Service vs. Provider
tylermcginnis.com
tylermcginnis.com
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).
At this point the angular team should probably just deprecate module.service and remove it from the docs to avoid causing this massive confusion.
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?
});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.
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.
.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();
}
});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.
That said, I echo spion's comment, that all this confusion is a sign that the API could use a bit of cleaning.
If you want to learn more about the subject: http://stackoverflow.com/questions/14833326/how-to-set-focus...
<sarc/>?
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.
The world will never know what software monstrosities have been perpetrated for fear of appearing insufficiently smart.
Some days my vim looks like (mostly Directives):
----------------------------
| | | | | |
| | | |-----------|
| | | | | |
| | | |-----------|
| | | | | |
----------------------------
And I'm thinking: Oh god what's happening, is this the abyss?i find React's implementation more clever, by giving you a single environment (JS) to declare your view's template and logic.
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.
> (...) 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.
This does not make sense. React.js whole point is writing components that do emit HTML and re-render themselves (and children). Now the only thing the developer has to do is react to events (implement callbacks) and change state (setState), the pipeline takes care of the rest. Not only it's impossible to "cheat" by changing the DOM directly from outside the component (a re-render would remove the changes), it's also more work, so it's not cheating at all.
In reality, the clever thing about React is that you start treating data (markup) as code (React.DOM), instead of introducing crutches to work directly with HTML.
Angular does not mix Presentation and Business logic. React doesn't inherently mix the two, but it doesn't dissuade it either.
> This does not make sense. React.js whole point is writing components that do emit HTML and re-render themselves (and children).
Yes, but it's writing code in Javascript that emits snippets of HTML or DOM. I'm generally not a fan of this approach. Even just just iteration requires jumping between the two, and often breaks up the page into multiple smaller segments in cases where it really doesn't need to me.
I dont care about this but let's just not pretend Angular solves the HTML template in code issue . It's far from inobstrusive.
Yes, angular templates are templates, not pure HTML. That's the idea. I'm not sure what your point is there.
In Angular people can write
app.directive('myDirective', function () {
template: "<strong>oh no</strong>"
});
which is what I think they were getting at.One of the nicest things about React.js is not having to deal with such a layered architecture, you work at the right level of abstraction ("components"), and those components are composable. Some people freak out with JSX but it pays off to finally have a proper GUI pipeline for web apps instead of manipulating the DOM directly, or being limited to directives embedded in HTML.
Used backbone a few times, always turns into a train wreck.
I know what you mean by Backbone, and all I can say is that often wiring up the views is the culprit. Models and routers work nicely and that's all I used from Backbone in this project.
Was that too snarky?
It's crazy.
- 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.
People see the word "Factory" and for some reason assume that it's somehow a Java enterprise bloatware feature. Nevermind that "Factories" Angular are
a) Nothing at all like Factories in Java
b) Something you don't need to use, and most Angular apps likely don't
c) Really useful when you do need them
If AngularJS is too heavyweight for what you're trying to achieve, it's not he right tool for your task. It's like complaining that a forklift isn't a very good hammer.
Angular is used to build thick heavyweight client applications. The sort of thing you might use to build a complete desktop-style application in the browser running in offline mode.
Mind you it's still surprisingly good at smaller applications as well. But if your solution can be solved with a few lines of jQuery, then you don't need Angular.
And that's not to say I love angular - it was just the least worst option available with the requisite power and flexibility at any level of maturity.
Intercooler is a little library built to play well with other web technologies, like AngularJS, EmberJS and Turbolinks. Use the right tool for the particular job: Intercooler won't get in the way.
From what I see out there, thought, there are a lot of apps that could be done with something simple like intercooler (e.g. Stripe) that are using complicated MVC frameworks.
Services and Factories are just syntax sugar on top of Providers, most times you won't need the full power of a Provider, so a Service is a name for a Provider with the commonly-needed defaults provided. Usually you won't need Providers, but they are there when you are doing something really weird.
From the docs: "The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe." https://code.angularjs.org/1.2.16/docs/guide/providers
Seems to me all those patterns should more be seen as framework internals rather than end-user features. The user side of angular really remains very light. Nothing like java spring for example.