Software Alchemist

I am constantly seeking answers and ways of transforming desires into reality by coding

AngularJS - Superheroic JavaScript MVC Framework

| Comments

I’ve been working both on frontend and server-side at Twilio. This has led to form my opinion that to make HTTP scale better, one shouldn’t use it to serve HTML at all. Rather, only serve data using HTTP and make it pretty on the client. In addition to offloading most of data processing to the client and making server lighter and less loaded, this decoupling achieves two important things:

  • Frontend code can live on a different cycle than your service code.
  • Perceived end user experience is a lot faster, since ongoing client/server communication is only about data exchange and not rendering logic.

Superheroic framework

There are a lot of JavaScript MVC frameworks out there nowadays. Why should you bother to learn yet another one. There are several reasons why I consider AngularJS to be a truly superheroic framework.

Testability

Testing done right is hard. I’ve always thought that the reason I haven’t seen appropriate testing was because I’d been using PHP and PHP is… oh, you know… Wrong! The reason I haven’t seen proper unit testing is because it is not widely used. Dependency injection allows for decoupled and unit-testable code, yet it is still largely misunderstood in Ruby and Python communities and they are just starting to get it. JavaScript is, naturally, no exception.

Well, good news, AngularJS is built by a team of really smart people, one of them, Miško Hevery, is a well-known test advocate, who has a series of Google Tech Talks on Unit-Testing, Clean coding and other interesting stuff that you should definitely check out. He also blogs about interesting programming related topics.

AngularJS comes with a built-in dependency injection framework and documentation has plenty of examples of writing unit, functional and end-to-end tests. Dependency injection container also allows for easy integration of 3rd party JavaScript into the framework, so all code feels at home.

AngularJS is an HTML pre-compiler, which means that your templates become really powerful and gain dynamic capabilities like conditionals and iterators, everything you expect from a server-side HTML framework. However, due to the nature of the environment AngularJS runs in, there is no need to pass data to templates, rather you work directly inside of your controller, assigning data (and functionality) to controller properties and your views get updated instantly - very useful feature if your data comes, for example, from an HTTP api.

Philosophy

AngularJS’s philosophy is enhancing HTML to what it should’ve been, had it been built with web applications in mind. This means that AngularJS templates use custom attributes, prefixed with ng: for adding dynamic capabilities. It seems a little unclean at first, but truly makes up for it with the speed that it lets you iterate on templates. And of course you can create your own ‘widgets’ (new HTML tags like <ng:switch></ng:switch>) and ‘directives’ (custom HTML attributes like ng:repeat). AngularJS literally re-compiles the DOM tree on initial page load to handle those. Ability to express your view logic using real markup code is indeed empowering.

Usage

In its simples setup, AngularJS does not require any manual initialization steps, except for including a script in a page and adding ng:autobind attribute to the <script/> tag. Manual initialization is still possible.

As I mentioned before, AngularJS let’s you set up custom directives and widgets. Couple of the ones that I have are:

  • ng:sort - a directive I use on table header fields to set up sorting
1
<th ng:sort="name">Name</th>
  • ng:timeago - a widget that displays a date in time ago format
1
<ng:timeago from="Mon, 27 Feb 2012 15:28:53 -0800"></ng:timeago>

In addition to markup extensions, you get ability to create custom services, that can be injected in your controllers, directives and widgets. This lets you re-use even more code and separate concerns better. Some services that I created for my UI are various HTTP Clients and Notifiers.

Controllers, this is where you start developing AngularJS application and, depending on how large that application is going to be, this might be the only place you need to know about. Controller in AngularJS is just a regular JS object (one of the things I love about AngularJS is that you don’t need to extend anything… ever… I dislike inheritance for reasons I stated in earlier posts). You can have some initialization logic in its constructor and you can inject some services in it using provided injection api.

1
2
3
4
MainController.$inject = ['api', '$location'];
function MainController(api, $location) {
  // code goes here...
}

The above example would tell AngularJS to inject ‘api’ and ‘$location’ services to my MainController upon initialization.

Finally, you initialize your template to use some controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!doctype html>
<!--[if lt IE 7]><html class="no-js ie6 oldie" lang="en" xmlns:ng="http://angularjs.org/"><![endif]-->
<!--[if IE 7]><html class="no-js ie7 oldie" lang="en" xmlns:ng="http://angularjs.org/"><![endif]-->
<!--[if IE 8]><html class="no-js ie8 oldie" lang="en" xmlns:ng="http://angularjs.org/"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js" lang="en" xmlns:ng="http://angularjs.org/"><!--<![endif]-->
<head>
  <title>Page Title</title>
</head>
<body ng:controller="MainController">
  <!--
    markup goes here
  -->

  <!-- AngularJS -->
  <script src="js/libs/angular-0.9.19.min.js" ng:autobind></script>
</body>

Advanced usage scenarios like multiple pages are also supported using ng:view widget and $route service. AngularJS lets you register controller/template combinations on various routes for those use cases.

Be a superhero

AngularJS makes building interactive web-apps a task even such a front-end newbie like myself can handle and make colleagues go ‘wow!’. I definitely recommend using it as tools it provides let a project grow and stay decoupled and simple, which I feel is a problem that hasn’t been solved properly (until now that is). AngularJS is on GitHub and accepts contributions in a healthy cycle, so if you want to go beyond just using this brilliant framework, you can definitely leave your mark in its codebase.

Comments