AngularJS is the new popular client-side Javascript application
framework developed by Google. We have recently adopted it at Vista
Higher Learning for building our latest features that require a lot
client-side logic. Now that I have a few applications under my belt,
it’s time to talk about my experience.
If you want a quick TL;DR: I think AngularJS is good, but it has a
steep learning curve and there’s no well defined set of best
practices.
Note: I will be using plenty of terms that will probably only make
sense for people that have used AngularJS.
The Good Stuff
These are the things that went well. The things that made me glad that
we chose to use AngularJS.
Easier Testing
Our Javascript test suite uses Jasmine. AngularJS is built with test
frameworks like Jasmine in mind. AngularJS could tends to be easily
testable due to dependency injection. When the components of an
application don’t rely on global state, it is easier to mock services
for unit tests.
Separation of Concerns
AngularJS stresses separating the view from the data structures and
logic behind it. I think everyone that’s written a somewhat complex
JQuery application can relate to the mess of CSS selectors and click
callbacks that the code quickly degenerates into.
AngularJS allows you to break up the DOM into logical chunks that are
handled by separate controllers. Treating the application as many
small pieces working together rather than one giant DOM blob keeps the
code clean. Message passing via $emit and $broadcast keeps
controllers loosely coupled to each other.
No More JQuery Spaghetti
Directives, the strategy for encapsulating DOM manipulation, are
wonderful. It is an elegant solution to the mess that was JQuery
selectors and event callbacks. AngularJS comes with a lot of
directives out of the box to handle the most common stuff like
showing/hiding elements, handling clicks, dynamically setting CSS
classes.
More Maintainable Code
AngularJS is feature-rich. It does a lot on your behalf, which greatly
reduces the amount of boilerplate code needed to get a prototype up
and running. I had the opportunity to essentially rewrite an existing
JQuery application using AngularJS. The results were clear: The
AngularJS version had fewer lines of code, was more readable, and
was easier to debug.
Bumps in the Road
These are the things that didn’t go smoothly. They boil down to
AngularJS having a steep learning curve and ill-informed software
design decisions on my part.
Understanding the Magic
A lot of things seem to happen by magic. For example, it is possible
to make a asynchronous request and get a promise object in
return. When the promise is assigned to a variable on $scope,
AngularJS not only knows to ignore it while the request hasn’t
finished, but it will re-assign to that variable the value of the
asynchronous call when it completes. It is a nice feature, but it
takes some digging to find out what is really going on.
Poor Documentation
I know I’m not the only one that hates the official AngularJS
documentation. The documentation is getting more complete, but it’s
still not very useful. Functions frequently have a blurb describing
what they do, but no explanation of the parameter list. It’s hard to
use a function that doesn’t describe what it expects for input.
When the documentation confused us, which it did frequently, we turned
to the AngularJS book from O’Reilly for help. I need to get around
to reading more of it.
RESTful Resources and Rails
AngularJS claims to be targeted at CRUD applications, but using the
HTTP backend and the Resource abstraction that sits on top of it was
particularly difficult. A good amount of time was spent on trying to
get the HTTP requests from resources to conform to what our Rails
backend expects, like root-wrapping.
Bloated Controllers
I frequently made controllers that had too much state and logic that
should have been extracted into services/factories/etc. A controller
would start out slim but would quickly grow to several hundred lines
of code as features were added. Controllers should be the middle man
between the view and the model and that’s it.
Some tell-tale signs that a controller is becoming bloated:
- There are a lot of private functions (not defined on $scope)
- Functions are defined on $scope just so you can unit-test them,
but are never used in the template
I attribute controller bloat to a lack of knowing the appropriate uses
for other AngularJS components. It was easy to just keep adding to the
controller.
Conclusion
Overall, I think things went well, but I (and the rest of my team)
made a lot of beginner mistakes. But that’s the learning process,
isn’t it?
Now that I know more about AngularJS, it will be easier to make better
design decisions moving forward.
I believe that as AngularJS continues to mature, some concensus in the
community about best practices will emerge that will make things
easier for beginners.
From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.