
Complexity Creeps: Why I'm Concerned for the Future of Angular.js - bcrawford
http://daemon.co.za/2014/03/complexity-creeps-concerned-for-future-of-angular/
======
wprl
I too think Angular is overly complex and "magical."

The JavaScript world should be learning from the mistakes of monolithic and
semi-monolithic frameworks such as ASP.NET and SEAM not trying to recreate
them.

For my part I'd like to see separate libraries for events, views, models,
syncing models to persistent storage, and binding models to forms. Small
micro-libraries allow maximum flexibility and efficiency, and facilitate more
maintainable code.

The way that Angular violates separation of concerns between presentation and
view is another symptom of a monolithic approach, and a step backwards in HTML
client software design.

~~~
AdrianRossouw
How I feel about angular now is that it's a vision of what web development
could be like in the future.

A lot of this stuff only really makes sense once the entire environment is
present. Polymer is actually fairly similar, but trying to tackle the problem
from a different angle.

It has the potential to do less in the future, and I think right now it's an
interesting proving ground for and ideas and teaching people to think about
things differently.

You should see this slideshow about their plans :
[https://docs.google.com/presentation/d/1Gv-dvU-
yy6WY7SiNJ9QR...](https://docs.google.com/presentation/d/1Gv-dvU-
yy6WY7SiNJ9QRo9XayPS6N2jtgWezdRpoI04/present#slide=id.p)

I'm much much more comfortable with backbone myself. If I didn't specifically
set out to build a couch-app, i would not have been able to justify using
angular.

interestingly, i realized i like backbone for the opposite reason i like
angular. I don't actively expect it to get more complex over time. It just
feels like each new release 'tightens up' the formula.

~~~
wbillingsley
Thematically, I'd say Angular's dependency injection is "supposed" to be
resolved by the tooling. If you look at Angular.dart, it doesn't have this
particular hack because it uses the type system to resolve what to inject. But
Javascript doesn't have static typing... "specify it twice (as a list of
strings, and then a list of arguments)" is a fairly ugly and error-prone
solution. Specify it once and let the tooling do the work seems like a
reasonable idea.

I tend to find that most of the awkwardnesses I come across in Angular
likewise come from the underlying nature of Javascript and HTML. As a concept,
Angular.js seems to me to be fairly straightforward -- client-side compositing
of templates against data (without imposing constraints on the type of data),
plus routes and a promises library for http calls.

~~~
AdrianRossouw
"specify it twice (as a list of strings, and then a list of arguments)" is
going to result in localized errors, in your own code, not spread through all
7 levels of dante's museum of abstractions.

Doing it at build time is also preferable to trying to do it at runtime, like
it does now.

I would agree with your assessment, otherwise. I just think that this specific
technique was railing against JS a bit too much, and was ultimately a dead
end.

Interestingly, the new DI framework also uses ES6 and traceur.

------
edanm
While I do the think author makes too big a deal about this, I _very much
agree with them_.

The main issue is whether or not we should be teaching people, as a first
brush with Angular, to code things with "automatic Dependency Injection",
where the types are inferred from variable names. The alternative, and only
way to code a "real" application, is to pass the names of things you want
injected as strings.

For people unfamiliar with Angular, this difference means turning:
myFunction(Dep1, Dep2) into myFunction(['Dep1', 'Dep2', Dep1, Dep2) (more or
less).

Doesn't seem like a big deal, does it? But I think the decision to teach
people the "bad" way to do things, all for the sake of making things
"simpler", is completely wrong, and misunderstands what kinds of complexity
people have a problem with.

Complexity isn't telling people "write the same word twice, cause that's how
it works". Complexity is telling people "here's _another thing_ you have to
learn about this framework".

This is a small matter, but it isn't trivial, and is a common mistake with
Angular.js (hiding the wrong kinds of complexity).

~~~
AdrianRossouw
I'm only making a 'big' deal about this because I have given this serious
thought.

This is the third part in a series of articles where I was trying to
understand why my intuition was telling me that there was something not quite
right about angular.

I finally managed to track it down to this specific little thing, and how the
unintended consequences of a feature like this could have far ranging
consequences to it as a viable platform.

My reasoning was not about how crazy this is now (which it is), but how this
could end up 5-10 years from now if it doesn't get removed now.

~~~
ilaksh
Why would you expect Angular or any current platform to be relevant in 5
years?

~~~
edanm
Most platforms, at least major ones, ARE relevant for many years. Of course we
have yet to see if Angular will be one of them, but it's looking like it will.

------
AdrianRossouw
This is part 3 of this series of articles

1\. i was wrong to be afraid of angular.js
[https://news.ycombinator.com/item?id=7384937](https://news.ycombinator.com/item?id=7384937)

2\. why i was wrong to be afraid of angular.js
[https://news.ycombinator.com/item?id=7394959](https://news.ycombinator.com/item?id=7394959)

This is where i discovered the exact thing about angular that freaked me out
the most, and how I was finally to get down in words what I felt about it.

I made a github issue about it, and the devs acknowledged the issue, saying it
was no longer part of angular 2.0

~~~
batoure
>I made a github issue about it, and the devs acknowledged the issue, saying
it was no longer part of angular 2.0

Ok so I read all both of your other articles and found them to be interesting.
I was disappointed that there wasn't some kind of afterword to go with the
sabre rattling. Seeing that you put in an issue makes me feel alot better
about the whole series.

As I read these I kept thinking... yeah but... and then thinking of a feature
that annoyed me that changed from release to release.

And ultimately I think the biggest thing I have always liked about angular is
how quickly the community has learned from potential mistakes and shed chaff
code....

~~~
AdrianRossouw
I was always going to need to put this into an issue, once I identified why it
bothered me.

I think angular is really special because I can see it getting simpler. I
almost never see that in software.

They have shown that they are willing to change, and I think that they have
the right people in charge to do it.

I think you are going to see some serious changes for 2.0 though. Now they are
on semver, stuff is going to have to shift pretty majorly between major
releases. You can see some of that in angulardart already.

I look forward to it.

~~~
batoure
I'm also pretty excited to see the next release.

I have read about potentially including lazy loading in the base which
personally would be really huge. Not having to integrate Require would be a
pretty interesting to me if it happens

~~~
AdrianRossouw
have you met my friend [1] browserify?

I'm probably not the audience for require.js, because I've never had a
situation where I was forced to not have a build step. Once you just accept
that there's always a build step, life becomes so much easier.

[1] [http://daemon.co.za/2014/03/subtly-meta-introduction-to-
brow...](http://daemon.co.za/2014/03/subtly-meta-introduction-to-browserify)

~~~
batoure
>Once you just accept that there's always a build step, life becomes so much
easier.

Sigh... but I don't want there to be a build step... :(

~~~
AdrianRossouw
I feel for you man. I really recommend you just try to build something, even
if it's a little demo of some sort, with the assumption that you are going to
have a build step.

I just found that the result of that assumption ends up with something that is
a lot easier to work with and reason about, than trying to rail against it by
using something like r.js.

------
ilaksh
As far as the particular issue he picks on, he is making a big deal about
something that's not, at least if you accept the general premises of Angular,
and trying to pin the core of his whole argument on that. Which is dumb.

Anyway, I have used many, many different UI frameworks on different platforms
over the years. Including different .NET systems, Backbone, Angular and to
some degree web components. And many other lightweight and heavyweight
systems.

I am actually amazed that developers are not immediately seeing the obvious
advantages of Web Components (with Polymer for now).

I am amazed that people are still trying to master AngularJS when we have
Polymer. (At least the people who can tell their users to use a new version of
Firefox or Safari, which is actually quite a lot of web apps these days,
although obviously not all).

Angular is very obviously more complex than necessary.

Very few people are going to be with me on this, but this whole idea of
separating out scope and avoiding global variables at all cost has got to the
point where it is just ludicrous. And the only explanation is that this stigma
about global variables has a religious and un-questioned association with
incompetence. Unfortunately that particular cargo cult can lead to things like
Angular DI.

Why aren't more web developers excited about Polymer and Web Components?
Because many web developers, despite experience with Angular, get distracted
by DI and other over-complex topics and somehow fail to completely grasp the
basic concepts and advantages of what a user interface component is and does.

~~~
acjohnson55
I disagree with you that the hacky DI scheme is something that should be
ignored. It's brittle and really has no place in the core of a library like
this. It's not an end of the world thing, but it's definitely worth
addressing.

I totally agree with you that Angular is overly complex. I feel like they
somehow either overshot or undershot the correct layer of abstraction, and I'm
not sure how. It can produce really elegant projects for sure, but when you
need to actually understand what's going on...prepare to navigate a whole new
world of linkers, compilers, injectors, scopes, directive options. The spiral
just keeps on going.

I don't get the defense of global variables. I feel like it's been proven time
and time again that the trouble of encapsulating code and explicitly coupling
parts of an app through clear interfaces pays dividends. I think class and
module patterns have been a major turning point in the maturation of
Javascript. I'm hoping that when we finally get native opinions of these
concepts in ES6, we won't need so many reinventions of the same thing.

~~~
ilaksh
Hm. Forget I mentioned the term "global variable" since it is a religious
term.

I am not trying to argue against proper encapsulation and coupling/decoupling.
Those things are great. Classes and modules and great. Not sure how you see me
as attacking those things.

Say I am working on a web application and I want to use AJAX. I should not
have to keep saying in every place that I want to use it "oh by the way I am
using AJAX".

If you agree with this then exactly what sort of encapsulation and coupling
would you recommend for the overall application to achieve not having to keep
saying that it wants to use AJAX?

~~~
acjohnson55
I think you should basically say "oh by the way I am using AJAX", whether that
means using Angular-style DI or require or a mixin some other means. In a
language with a built-in concept of modules, you'd have to import or include
something like that, wouldn't you?

There are some practical benefits, aside from the general happiness provided
by namespacing. Not that every single app needs this, but it's pretty handy
for example to be able to substitute a mock AJAX service for testing and
offline development purposes.

------
carsongross
It isn't ready yet (another few weeks until a 0.1) but I'm working on a
simpler UI framework that lets you bind HTML elements directly to REST-ful
URLs, cutting out a big swath of complexity for many apps:

[http://intercoolerjs.org/](http://intercoolerjs.org/)

Again, _this is not ready yet and I 'm actively changing things_, but if you
are interested in an AJAX framework that is concerned with keeping complexity
to a minimum, it might be worth checking out. Comments and criticisms very
welcome.

~~~
adambratt
I just created a post about this on StackOverflow...

Awesome!

[http://stackoverflow.com/questions/22386214/whats-the-
best-w...](http://stackoverflow.com/questions/22386214/whats-the-best-way-to-
convert-server-side-html-into-a-javascript-mvc-on-page-lo)

------
badman_ting
I think DI in Angular should be an opt-in thing, too confusing otherwise. I've
had moments where I thought I was just writing a regular function, and then
Angular started throwing exceptions because it was trying to inject
dependencies based on the argument names. (And the solution was to write a
function with no arguments that returned the actual function with arguments!)

There are conventions around what string maps to what thing, so that sometimes
strings like "controller" or "provider" are inferred and not required to be
specified. This is bad -- things should just be referred to by their full
names.

It would be nice to have the ability to ask for things directly in require-
style function calls instead of having them be parameters to a function. It's
actually sort of crazy that you can define a controller (for example) with
angular.controller('MyController', function(){}), but then you can't ask for
it back with angular.getController('MyController'), or whatever.

All this makes it a lot harder to try things out in the console, and lengthens
the feedback loop of determining what works and what doesn't.

And I didn't even know about the minification thing. That is legitimately
terrible.

~~~
johnny635
You need DI to do unit tests properly.

~~~
zwily
Isn't the problem Automatic DI, and not DI?

------
apinstein
It's interesting that he has a visceral reaction to the "hackiness" of
Angular's clever way to do runtime DI but no visceral reaction to the fact
that the problem was created by a third-party program which was instructed to
purposefully obfuscate the actual source code of his program before delivering
it to the runtime... the JavaScript world is indeed a funny place.

That said, I am empathetic to his argument. But as a very happy Angular user,
the benefits that are gained by having a runtime DI layer that works such that
it can be built into the entire platform so far outweigh the one-time tooling
change that it doesn't bother me at all.

The rest is a slippery-slope argument that I don't think is fair. If you trust
Angular as a project, then you have to trust to some extent that they'll make
sane decisions. Since this particular clever hack is the only one that won't
get "better" over time as runtimes improve, I think that they deserve the
trust so far.

~~~
AdrianRossouw
DI is fine, i was just concerned that they have something that breaks as the
first recommended way to do something. Much less that they have it at all.

Minification pretty much counts as 'normal use' these days, as much as we all
have a distaste for it, we really can't change it.

You should watch the video on my post and tell me you are still comfortable
with it doing that at runtime.

And the slippery slope thing? I spent 10 years of my life building open source
projects with thousands of contributors and untold thousands of users. That's
experience talking there. My point was that you can't deny the sufficiently
promising excuse to abuse it further, without admitting that it is flawed to
begin with.

My suggestion was that now that the ngmin exists, make that the only way to do
it and remove all the crazy stuff out of the main execution.

I also said that clever hack is the only one that could never get better.
There's no standards path for it.

They have been shown to deserve the trust. they are removing the hackiness
from 2.0.

~~~
apinstein
Great ideas! Sounds like we generally agree. I read the whole post but didn't
watch the video or read all of the 2.0 stuff... though I am aware how their DI
hack works.

That said, the title of your post makes it sound like you think they're
heading off a cliff, but your response to me sounds like the opposite... I was
just responding to the tone set by the article.

I'll also agree that it is frustrating early in the AngularJS experience to
hit that minification bug. But it's easy to get over also.

~~~
AdrianRossouw
Yeah. I was mostly concerned about the fact that nobody was pointing this out.

If you read the [1] previous post you will see that I am remarkably positive
about it. My concern was that the answer to working around the DI hack was
always "dont do that".

Even ngmin is just a really elaborate way to 'dont do that'. With it's own
issue queue and grunt plugin and almost 22000 hits on google.

From working on open source for a long time, I know that existing code also
sets precedent. And i couldn't think of any way that you could keep using that
code for the next 5-10 years without somebody thinking of something else
'clever' to do with it.

They devs realized that though, without me. which is great news. You are in
awesome hands imo.

[1] [http://daemon.co.za/2014/03/why-wrong-to-be-afraid-
angular](http://daemon.co.za/2014/03/why-wrong-to-be-afraid-angular)

------
camus2
AngularJS is not complex , when I think complex , I think SpringMVC or Struts
complexity. AngularJS has problems ,but complexity is not one of them,
definetly.

Seems like JS programmers who only know JS think they can get away with
ignoring patterns like dependency injection, Guess what, in order for code to
be maintainable and testable it needs it.

Front-end is about GUI dev,and that's where OOP shines. It's high time for JS
folks to read classics like "Design Patterns" books, and embrace SOLID
principles , or AngularJS wont even help when developping their so called
"fairly large" apps.

~~~
AdrianRossouw
Nope. agreed.

I just felt that this little thing was complex, and that something like this
can spread over time.

I had no issue with dependency injection either, just the magic format.

------
meric
The author is concerned about _the future_ of Angular because of the
idiosyncrasies of _one method_ of including dependencies. I mean, really? Is
it so bad, the stench of automatic dependency injection, it overcomes all
other beneficial features of Angular, it would jeopardise it's future as a web
framework, such that it would lose compatibility with future browsers and your
web app built in angular will stop working, with no support available? IMO
it's a bit hyperbolic to suggest this is the case.

~~~
AdrianRossouw
no. i was worried about the fact that people weren't questioning the logic of
it, and that once this kind of magic takes hold ... it's really hard to take
it out again.

Nobody said anything about future browsers and losing compatibility.

I do think that if this kind of thing grows, the system will become complex
enough that developers will move to different frameworks that do similar
things but don't have all this magic and baggage.

------
jcampbell1
This seems like a one-sided overthinking of the auto dependency injector
(which is like 30 lines of code).

1\. The auto DI means beginners can get to "Hello World" in angular without
learning some wonky injector syntax. If Angular's goal was to bring some of
the jQuery crowd on board, then it was a smart move.

2\. The auto DI doesn't survive minification, so not all code can be copy-
pasted, and there are two different syntaxes. Unnecessary complexity?

I see no reason to make a bunch of analogies to argue on one side.

~~~
AdrianRossouw
Are you sure you're not just under-thinking it?

Those 30 lines of code require the hundred or so lines of ngmin to actually
work correctly, and then results in the extra (im assuming) hundred or so
lines of grunt-ngmin and all the tooling around that. And then all the tests,
the issues for the main project and all of the related projects, every bug
that anybody has ever faced with minification of angular apps.

The auto-di is not that much simpler than the array format, and the array
format is also actual valid javascript. They are abusing language features in
such a way as to bypass the semantics of the language itself.

The fact that it doesn't survive minification is a sign that you shouldn't
really be doing it to begin with. There are 3 different formats, and one of
them introduces some crazy magic into the main framework, that is all really
unnecessary and could just be as easily avoided. Auto-Di is the 'wonky' format
in any reasonable context, I'm afraid.

------
grumblestumble
\- AngularJS is a tool for building complex single-page web applications, not
brochureware. \- If you're building complex SPAs, you're going to require a
decent level of tooling. \- If you have a decent level of tooling, the points
in this article are meaningless.

As an aside, ngMin is the most trivial thing in the world to set up, and if
you can't figure it out, array notation is slightly painful but well worth it
for all of the tools Angular provides.

------
klochner
I still can't decide if angular dependency injection is more amazing or
revolting.

It's magic, it's non-intuitive, it breaks the standard paradigm that function
arguments have no external significance, and it doesn't add much real value by
just saving one extra line per function - _inject(fn, ...)_

On the other hand, it's elegant if you ignore all the above criticisms.

~~~
AdrianRossouw
just the inferred dependency injection.

and it's warped. as i stated in my article.

i don't mind the DI myself too much, but then, I also prefer commonJS =P

------
Bahamut
I'm a huge fan of dependency injection, it makes life infinitely better when
designing your code & testability.

That said, I'm somewhat sympathetic to this complaint - it turns me off
towards Backbone. However, I argue that it isn't nearly as bad as views with
Backbone. In addition, this is changing in 2.0 with a much cleaner injection
mechanism.

~~~
AdrianRossouw
dependency injection is fine. just the magic argument detection wasn't a good
idea.

Backbone views has nothing to do with this, imo.

The thing I miss the most when using backbone, and I use it a _LOT_, is
observables. Binding and unbinding model events can get really tedious.

Marionette really does help for that, but this stuff can still get out of
hand.

~~~
Bahamut
It does when it comes to not leaving your views in an ugly string
representation of html - you use a build process of some sorts to get around
that fundamental flaw so that you can still use a nice html template file.
That alone was enough to sour me on Backbone, hence the comparison.

This flaw in Angular isn't nearly as deep was my point.

~~~
iLoch
HTML is HTML, why does it matter what file type it resides in? All my
templates are stored according to the view's type within my ./templates
folder. If I want to include the HTML in an "actual" HTML file I can do that
too. Have you even used Backbone?

