summaryrefslogtreecommitdiff
path: root/posts/2013-08-08-angularjs.md
blob: 0ea8c19f3859a9ffbf99a7f2a264a029cbeaf497 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
title: AngularJS Post-mortem
date: 2013-08-08 11:00:00
tags: web, javascript, angularjs, wsu
summary: AngularJS likes/dislikes and what went right/wrong
---

[AngularJS](http://angularjs.org/) 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](http://pivotal.github.io/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](http://shop.oreilly.com/product/0636920028055.do) 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.