All that is terrible in AngularJS

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at:, or follow me on Twitter.


The scope of a variable is the part of the program where the variable can be legally referenced. If your system has variables, it has some concept of scoping.

Angular has a DSL that is entangled with the HTML and used primarily to express the data-bindings between the UI and application code. This has variables, and thus a concept of scopes. Let’s take a look at it. Consider for example ng-model:

<input type=”text” ng-model=”obj.prop” />

This creates a two way binding on the property prop of object obj. If you type into the input field, the property prop updates. If you assign to the property prop, the input field updates. Neat.

Now let’s add some simple parts:

<input type=”text” ng-model=”obj.prop” />
<div ng-if=”true”>
<input type=”text” ng-model=”obj.prop” />

Question: What does obj.prop refer to in the second input tag? The answer is that it is literally impossible to tell what meaning of ng-model=”obj.prop” is by reading the code. Whether or not the two “obj.prop” names refer to the same thing depends on the runtime state of the program. Try it out here: If you type into the first input field first, the two inputs will share the same model. If you type into the second one first, they will have distinct models.


What’s going on here? Understanding that requires some knowledge of AngularJS terminology – skip this paragraph if you don’t care. The part that says ng-if is what’s called a directive. It introduces a new scope that is accessible as an object within the program. Let’s call it innerScope. Let’s call the scope of the first input outerScope. Typing “t” into the first input will automatically assign an object to outerScope.obj, and assign the string you typed to the property like so: outerScope.obj.prop = “t”. Typing into the second input will do the same to the innerScope. The complication is that innerScope prototypically inherits from outerScope, so whether or not innerScope inherits the property obj depends on whether or not it is initialized in outerScope, and thus ultimately depends on the order in which the user interacts with the page.

This is insane. It should be an uncontroversial statement that one should be able to understand what a program does by reading its source code. This is not possible with the Angular DSL, because as shown above a variable binding may depend on the order in which a user interacts with a web page. What’s even more insane is that it is not even consistent: Whether or not a new scope is introduced by a directive is up to its implementer. And if a new scope is introduced, it is up to its implementer to decide if it inherits from its parent scope or not. In total there are three ways a directive may change the meaning of the code and markup that uses it, and there’s no way to tell which is in play without reading the directive’s source code. This makes the code-markup mix so spectacularly unreadable that one would think it is deliberately designed for obfuscation.