AngularJS – The “bad” parts

In my current project I am developing an application using AngularJS as its frontend technology. The task was to break out specific parts of an existing rich-client and build a ‘fancy’ app to be used by a small part of the users.

Out of several alternatives we chose AngularJS and we are quite happy with our choice. I knew Angular beforehand, having used it in small private projects. So I consider myself as a slight Angular-fanboy.

But the other day a colleague of mine from another team asked a fair question: “You are telling all these raving things about Angular all the time. But what does suck about it?”

I had to think hard, but I couldn’t tell any flaws right away. So I started to compile things that bother me about Angular. And sadly :) this list grew to some degree.

In this post I’d like to present to you my 2 cent about those bad parts. Those bad parts aren’t bad per se. It’s rather a list of things my team and me had some more or less hard time with during our development. This list is supposed to serve mainly as a reminder for me.

I’m still a fanboy, but I think those raving reviews can be found by some googling. (I will compile my ‘Good Parts’ list later on :))

But let’s begin. Those points are more or less in random order:

Learning curve

Though you get to first successes rather quickly, the learning process might take you longer than you might expect. This short post describes it quite well. Some moments where I stumbled a little were $scope communication and visibility, $promises and custom directives.

Promises are hard

As I mentioned before, I think the concept of promise is kinda hard. Useful, but overwhelming at first. There are many places throughout your Angular app where you eventually stumble upon promises, the most obvious one being $resource. Coming from a java world, I haven’t used promises (or futures) quite that often.

Not exactly lightweight

Angular seems to be a tiny, lightweight thing, when looking from the outside, but it really isn’t.

For example: The HTML templates you develop and use with Angular are just that: templates. Angular compiles and transforms those templates into something similar looking but different thing. Think of JSP => HTML conversion, but on the client side. So you get an implicit additional layer, you might not expect.

It works like a charm, but it gets me shivers now and then ;)

Scope

Also mentioned before, you have to understand the relationship between controllers and scopes and how to stack scopes properly. Communication between scopes is something you don’t do right the first time. You could do events (event-hell), $rootScope (global state), services (view not accesible), or access a parent scope (might seem magic) or perhaps more. We had to spend some time thinking about this and to discover the possible ways.

Debugging

This might be more of a tooling issue. Using Batarang the overview of stacked scopes gets quite overwhelming. Most of the time we fell back to console.log().

Dot

I guess this is everyones favorite. We stumbled across this more than once.

Really not usable in every use case

This might be a topic for another post. Angular should only be used if you are developing a “real webapp” where you need all these interactive gimmicks. If you are developing a plain old form website, it might be too much, and a simpler approach might better fit your needs. As with every technology, look at your requirements first :)

Forced to use node.js

Working in Java based shops, node.js has this esoteric aura and is frowned upon. But if you want to develop properly and use all these shiny recommended tools like grunt, bower etc. you should at least have a working node.js installation on your dev machine. And it doesn’t hurt to have node running on your CI machine as well. We found it handy to use express to sketch some early REST endpoints, that could work as mock endpoints. Feels easier than, say, use Jetty/Jersey to do the same.

Grok Javascript and prototypical inheritance

If you stumble upon the dot issue I talked about earlier, you’ll understand why. Scoping relies heavily on the prototypical inheritance. You might not guess its effects the first time, you will eventually read about it and get some understanding.

Decent development only with Chrome

We have to build our application for a newer version of IE. Like most of us. But the best development tool Batarang is only available in Chrome (at least now). So you will have to use both.

Syntactical overhead to prevent minification issues

When you declare a controller and its dependencies you could just rely on the naming conventions.

But in case you minify your code, the naming gets lost

This clearly is a duplication, and kind of ugly I think.

All Dependencies on one page

Even if you compose your app from multiple modules, all dependencies are loaded upfront. There is no built-in dynamic loading mechanism. Angular 2.0 might have such feature. One might use libs like require.js to leverage this, if it is a problem.

This might be a problem, if you face a really large application.

Pluggable subapps hard

If you are developing a larger app,  you may want to compose your app from smaller apps (like a portlet, or Eclipse RCP/OSGi). This is possible, but you have to homegrow your solution. Communication between those subapps seems nontrivial. Say you have a sidebar to which you might want to contribute from many possible unknown parts. Yes, I admit this is quite unfair, as no other contender to Angular (afaik) does this. But if you want to port some real largish application to the browser this might be something you need.

Slightly bad press

There is some discussion going on, whether Singe Page Applications (and AngularJS) are a proper way to structure applications. One might be intimidated by that.

For example here or here or here or here.

Some criticism is justified, some not. I’d say: If your requirements call for a SPA, go for it.

Error Messages could be better

Looking at this:

Error: [$injector:unpr] Unknown provider: PageSizeServiceProvider http://errors.angularjs.org/1.2.16/$injector/unpr?p0=PageSizeServiceProvider%20%3C-%20PageSizeService
at http://localhost:8000/app/vendor/angular.js:78:12
at http://localhost:8000/app/vendor/angular.js:3705:19
at Object.getService [as get] (http://localhost:8000/app/vendor/angular.js:3832:39)
at http://localhost:8000/app/vendor/angular.js:3710:45
at getService (http://localhost:8000/app/vendor/angular.js:3832:39)
at invoke (http://localhost:8000/app/vendor/angular.js:3859:13)
at Object.instantiate (http://localhost:8000/app/vendor/angular.js:3880:23)
at http://localhost:8000/app/vendor/angular.js:7134:28
at link (http://localhost:8000/app/vendor/angular-route.js:913:38)
at nodeLinkFn (http://localhost:8000/app/vendor/angular.js:6579:13)

a seasoned Angular Developer might guess what the problem here might be, but a beginner is put off.  In this more or less trivial example the provided Error website (great idea!) works fine, but often times the provided website was rather misleading.

REST Backend

If you are not able to provide a REST backend (that speaks JSON) to your data, things might be a bit harder. $resource and friends assume you use REST. I don’t know if there is an elegant way to access SOAP backends.

Forced to be asynchronous ($resource)

Speaking of $resource: Angular proposes the usage of asynchronous resource access. Though I think this is good after all, many beginners (me included) wished to have synchronous way to access a resource, to get an easy headstart.

But hey, jQuery does this as well.

Writing directives is not exactly easy

Directives are a powerful concept and it’s surely possible to master them, though I haven’t grokked them in their full glory yet (what the heck is transclusion? ;)).

For example: I always wonder what the syntax might be to bind the directive to attributes and element?

Not exactly intuitive.

Lately I’ve seen directives as a first code example in a beginners talk. Might not be my first choice.

Besides the official docs I enjoyed reading this and this.

Vast forest of third party components

Lately covered by this article. Though I tend to disagree with a fair bit of this article, I think there may be a point here.

There are third party components for every scenario you might think of. It’s not easy to review them all. Some are very good some are of poor quality.

But on the other hand there are components for every scenario you might think of. An active community is a good thing after all

Usage of jQuery can be inconvenient

This seems to me like a minor issue, but I include this anyway:

If you want to reuse some functionality supplied by jQuery or jQueryUI chances are that this will not work out-of-the-box. A colleague of mine wanted to reuse a DatePicker iirc and he spent a day integrating it. But most of the time, there will be some already built Angular Directive that will help you.

Math.round seems not to work in templates directly

Another more or less minor issue: Though you can use some JavaScript expressions in your template. We stumbled upon a tiny glitch (really?). You cannot use Math.round directly. We solved by using a controller function, a filter might be another solution.

 

So, if you kept reading until now, thank you very much! I didn’t expect this article to become this long. ;) Stay tuned for the good parts part ;)

Eine Antwort zu “AngularJS – The “bad” parts”

  1. […] promised in the “bad parts” article I now want to speak about some of the things AngularJS shines in my eyes. I promise to keep it […]

Hinterlasse eine Antwort