Learning AngularJS and Bootstrap

Recently I was asked to help build an desktop app to help manage a fairly complex set of data. Instead of enhancing the legacy tools, I saw an opportunity to migrate to a new set of HTML5 based tools and for myself to learn about the exciting new world of AngularJS, Bootstrap UI and Javascript – as a bonus I stumbled upon jQuery DataTables! While there is a lot to talk about in terms of jQuery / DataTables / Bootstrap, I am going to focus Angularjs for this post. It is by far one of the sharpest tools I have come across in a long time and I cant emphasis how excited I am by the explosion of cool tech happening in the web UI space right now.

AngularJS and JSON

As a quick example of how quick and easy Angularjs is and how it applies a basic MVC model. Lets start with our data, in this case a simple JSON string. Imagine this is dynamic and the number of elements is variable

[{name:"George", age:"32"},{name:"Mike", age:"50"}]

Next we write a small piece of Javascript which defines our angular app and controller. We initialize $scope.listOfNames with the above JSON data via a restful API. You can now use $scope.listOfNames globally throughout your code.

var app = angular.module("myApp", []); app.controller("myCtrl", function($scope, $http) { $http.get('restAPI.com').success(function(data) {
 $scope.listOfNames = data;
 });
});

And lastly, we describe the view in the HTML. Here we tell define the scope as using variables from myApp and myCtrl – each app can have multiple controllers. As you can see below, it’s very simple to say I want to loop through all values in listOfNames and generate a nice table dynamically.

<table ng-app='myApp' ng-controller='myCtrl'>
  <thead><tr><td>Name</td><td>Age</td></tr></thead>
  <tr ng-repeat='x in listOfNames'>
    <td ng-bind='x.name'><td ng-bind='x.age'>
  </tr>
</table>

End result will be a dynamic table based on the elements of listOfNames array. Of course it was a rather simple example, but I hope you can sense the power this offers you for extremely complex data bindings.

Name Age
George 32
Mike 50

Data Binding

Another basic but powerful feature is data binding. For example if you want to dynamically filter the table rows based on user input. Without writing complicated javascript, you can now simple bind your filter input in your HTML using

Search: <input ng-model="query">

Then add a filter to your table definition from above bound to the value of the input. Essentially the results of “x in listOfNames” is piped to the filter and actually you can chain a number of operations together this way including sorting etc.

<table ng-repeat="x in listOfNames | filter:query">

And as if by magic, your HTML table will dynamically change based on user input. Table is just one use case, you can apply the same idea to any number of controls such as dropdown and lists etc.

AngularJS Bootstrap UI

Now if your starting to wonder, yes there are a million pre-defined controls out there where others have done the work for you. Bootstrap is one such framework and while you can use it directly, I played around with the Angular Bootstrap libraries. You can get all the common controls you need such as model and alerts here: http://angular-ui.github.io/bootstrap/

The advantage I found of using this rather than Bootstrap directly was that Angular has wrapped out all the boostrap components for you and they work out of the box with angular. So you only need to include the angularjs package. Here is an example of using angular to filter on the results of a type ahead control – where $viewValue holds the user input.

<input type="text" typeahead="city for city in list | filter:$viewValue | limitTo:8">

angularbootstrap

AngularJS variable scope

While all this is very cool and powerful, it is a bit of a nightmare to debug and get right the first time. One of the issues which took me a while to track down was dealing with variable scope. This topic is worth a whole article in itself so its best to read here: https://github.com/angular/angular.js/wiki/Understanding-Scopes

It basically means that each nested Angular tag generates its own set of scope variables if the variable is a primitive. The result is odd behaviours where data bindings do not work as expected. The suggested workaround is to always use objects as your variables rather than primitives, i.e.

$scope.name = { value: 'George' };
rather than
$scope.name = 'George';
Debugging Issues

As previously mentioned, debugging is a nightmare, but there is light at the end of the tunnel. It will be familiar for most JavaScript developers, but Chrome is your best friend. It is not just a browser, but also a powerful debugger – allowing you to step through your javascript code line by line as well and even fine tuning your site’s performance. It really is a beast of a tool for developers and once mastered, will save you a ton of time. To get to the screen, simply hit F12 on any Chrome browser.

ChromeDebug

I realise there are other camps out there that much prefer the likes of Backbone.js and Ember.js. Unfortunately I haven’t got round to trying those out yet, but if you feel strongly, please leave note to say which one you prefer and why. Happy coding!