AngularJS Pain Points

I’ve been using AngularJS for almost 3 months. I had heard quite a lot about Angular before this time – many people were talking about it being the ‘next big thing’ and how it could become the defacto JavaScript framework for client-side development.

At first glance I was very impressed with Angular – the two-way binding removes the need for constantly updating the view and the scope objects makes for a clean separation between the controller and the view. There were other elements which were very appealing as well – a complete documentation site, a focus on testability, and a clean separation of concerns through built-in dependency injection. As I said, at first glance it definitely looks very impressive.

Now that I’m more familiar with AngularJS I am unfortunately less impressed. The framework is definitely powerful, but there are various factors which seem to make Angular more painful to work with than I thought would be the case. There are definitely some great features in the framework, but I definitely don’t think Angular is the clear winner in the JavaScript-framework-wars by any means.

The Documentation

I’ve spoken to other developers who use Angular and the common complaint is always about the documentation. The Angular documentation is incredibly thin – meaning it briefly covers every topic – and suffers from a lack of code examples. For example, one of the things I struggled with early on was to use the $httpBackend module in E2E testing. Sure enough, there is a page in the documentation and it explains how to setup the $httpBackend object to mock out certain responses. However, after the 14-line code snippet the documentation simply states:

Afterwards, bootstrap your app with this new module.

What the documentation conveniently ignores is that you can’t simply inject a mock httpBackend into your application since your application will then stop working when you’re not in test mode. So you need to figure out a way to load all the test dependencies and setup only in test mode while avoiding possible issues when you deploy your application. There is also an additional dependency on the angular-mocks script which you need to include. These kinds of omissions are very common and can very easily cause you to waste fruitless hours experimenting with different solutions to find the answer.

Of course, since Angular is an open source framework many enthusiasts will simply see this as a community problem – the source code is available for anyone to read – we can simply write the documentation ourselves. While I disagree with the sentiment, I find this even more difficult with Angular since the framework is very large and complicated. It takes a substantial effort from any developer to understand the source code to the extent where writing documentation is possible. For example, the uncompressed AngularJS core library is 14,846 lines of code. Compare this to the the uncompressed core library for SpineJS which is only 1174 lines! I would be the first to advocate that lines of code is a terrible measure of source code, but the numbers definitely indicate that Angular is a large framework which makes the lack of documentation very painful.

The other problem with the documentation is the incredible lack of any SEO (Search Engine Optimization) focus. I say incredible because I would expect a library created and maintained by Google developers to at least be decently optimized for search, while the exact opposite is true. The Angular documentation site is actually a very good example of how bad SEO can be. For example, this afternoon I couldn’t remember all the different matchers for E2E testing so I simply googled it.

AngularJS e2e testing matchers google search

The only link to the Angular documentation is to a tutorial link – the actual page that contains the matchers is nowhere to be seen. If you add ‘documentation’ to the search term you simply get the root of the documentation site.

The Testing

Angular supports two types of testing – Unit testing and E2E testing (end-to-end). The Unit testing uses Jasmine (which is great) and the E2E testing is part of the Angular framework.

Angular does go a long way towards making your code testable (and you can definitely TDD most of it), but there are some rather painful issues along the way. For one thing, the documentation doesn’t really offer much in the way of best practices (at the time of writing, the Unit testing documentation has 6 sections which are blank) which means you will probably spend quite some time figuring out how to properly create your controllers and inject mock objects where necessary.

Once you get over the initial learning curve you will need to contend with 2 frameworks which have very similar – yet different – syntax. The Unit testing framework uses the popular Jasmine matchers while the E2E framework uses it’s own set of matchers. The documentation describes it as Jasmine-like BDD syntax.

The Angular framework doesn’t have any sort of test runner built-in, although Karma is suggested. Unfortunately this is another pain point. For example, this is some example output from a test failure in my current project (obfuscated, of course).

....................................
PhantomJS 1.9 (Mac) Validations should return false when none of the subfields are filled in FAILED
        Expected true to be falsy.
PhantomJS 1.9 (Mac) Validations should return false when only month subfield is filled in FAILED
        Expected true to be falsy.
................................................................................

Unfortunately the runner doesn’t give us any indication which file the test belongs to, or which line number. This means you usually need to do some creative grep-ing to find the culprit. To avoid this issue we have started to use describe blocks with the name of the controller or service, which is less than ideal.

The Overall Complexity

Angular is definitely a very powerful framework. It’s very easy to create some very powerful interactions with a few simple include statements and relatively little JavaScript (or CoffeeScript). However, this power comes at the cost of high complexity.

I find the argument usually made by staunch Angular supporters is that it’s pretty much always less lines of code than another framework. While I agree with this statement I think it’s a rather poor measure of a framework. If we were to draw a graph of complexity versus power in different JavaScript frameworks, Angular would plot very high on the power axis, but also very high on the complexity axis. The power of Angular comes at a high cost.

On this hypothetical graph there should be a sweet spot – where the additional complexity is no longer worth the additional power a framework offers. In my opinion Angular is perhaps slightly too far along on this tradeoff. It’s no use to be able to code a page in half the amount of JavaScript if it takes a new developer 3 times as long to ramp up on that code.

The bottom line is that Angular has a steep learning curve. Don’t underestimate it, especially given the lack of documentation and best practices.

Angular is still great

After all this negativity you might think that I’m completely against Angular. Not in the least. I am merely pointing out the different pains you might experience if you’re working with Angular on a daily basis.

Angular is still a great framework – it has some great features and it’s really powerful. But I wouldn’t declare it the clear winner in the JavaScript wars just yet.

Angular is simply another option to choose from for your next JavaScript project. It might be the right choice for you. Might.

Happy coding.