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 its 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.