I 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!
Well, 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?
Building 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.
The Angular guys aren't missing the point. I think it's the other way around.
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.
Funnily enough I'm working on a web application and I have used angular on a few pages and intercooler elsewhere. I really like intercooler but it's not even close to being able to tackle the parts that I used angular for.
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.
Yeah, I'm being doctrinare here, but as I say on the main page:
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
Yeap. I just coded a big client side, generic interface using angular, and i never really felt the need to understand the differences between factory, service and providers ( which i do now thanks to the article).
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.
well 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.
It'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.
You 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)
What 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?
i 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.
More 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.
I don't see how Angular does not mix HTML and presentation logic, the point of directives is exactly that. Also, separation of concerns is not about this (it's about encapsulation, see Dijkstra).
> (...) 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 mix HTML and presentation logic. That's the point, and this is desirable.
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.
a lot of people put html strings into directives so it has nothing to do with angular. Furthermore , in angular the HTML looks like a template, not just html ,with expressions , ng- everywhere ...
I dont care about this but let's just not pretend Angular solves the HTML template in code issue . It's far from inobstrusive.
You can cheat in any framework. The difference is that angular strongly encourages you towards one design, whereas React.js does not. (Directives are also not part of your normal daily workflow. Many projects wouldn't even use them).
Yes, angular templates are templates, not pure HTML. That's the idea. I'm not sure what your point is there.
After successfully implementing a project with React.js + Backbone models and routers, I'm now sure Angular is both unnecessarily complex and limited.
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.
Unfortunately it's a commercial product so no source. Drop me a mail though (see profile), I can give some pointers.
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.
Yesterday, 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 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.
To me, a large part of the value proposition behind angular is in a) making your app as declarative as possible and b) isolating resuable and imperative code in modules (directives or services in the parlance of angular).
the 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.
I 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).
Nope, 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.
Why 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.
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.
I 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.
That 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.
Thanks for clearing that up. I got really close to landing on this while playing around with Services, it seems, but somehow missed the revelation entirely!
That said, I echo spion's comment, that all this confusion is a sign that the API could use a bit of cleaning.
Angular 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.
59 comments
[ 3.8 ms ] story [ 106 ms ] threadWas that too snarky?
It's crazy.
http://intercoolerjs.org/why.html
- 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.
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.
[1] http://facebook.github.io/react/html-jsx.html
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
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.
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.
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.
.service('$timeout', function($window) {
});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() {
});is the same as:
.provider('foo', function() {
});And,
.service('foo', function() {
});is the same as:
.factory('foo', function() {
});is the same as:
.provider('foo', function() {
});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.