I will speak at JavaZone 2015

I’m excited to announce that I will be speaking at JavaZone 2015! If you did not know already, JavaZone is the largest IT conference in Norway. Up to 2500 software engineers gather each year in Oslo to attend 2 days packed with presentations, lightning talks and workshops!

I will be doing an hour presentation on the upcoming Angular 2.0; “Angular 2 + TypeScript = true. Let’s Play!”. Make sure to book your ticket today and I will see you in September! πŸ™‚

Advertisements

Updating $scope Data in Asynchronous Functions

One of the many lovely things about Angular is the fluid two-way data binding that we get with the framework. Although not entirely perfect when it comes down to performance, it saves us quite a lot of timeΒ and effort when writing web applications.

When it comes to asynchronousy, however, it should be noted that doing changes to your $scope data does not propagate to the view implicitly (!). In other words, if you do a change to a $scope variable from asynchronous context, the change is not reflected in the view. Let’s look at an example. Consider the following controller that uses JavaScript’s asynchronous setInterval function to update a counter every second:

function Ctrl ($scope) {
    $scope.counter = 0;
    
    setInterval(function() {
        $scope.counter++;
    }, 1000);
}

This code looks pretty good and dandy, right? Unfortunately, no. Although the counter does get updated every second, it does not propagate the change to the view. There are a couple of ways to solve this issue.

Invoking $apply Manually

The simplest and most straightforward way is to invoke $apply manually in the asynchronous context. Consider the following change to our initial example (lines 5 – 7):

function Ctrl ($scope) {
    $scope.counter = 0;
    
    setInterval(function() {
        $scope.$apply(function () {
            $scope.counter++;
        });
    }, 1000);
}

This change will force the counter updates through to the view.

Using Angular’s Asynchronous Services

This approach is case specific. For instance, you can use the services $interval or $timeout, which actually behind the scenes invoke $apply – relieving you from doing so manually. Considering our initial example, we can therefore inject and use $interval in our controller instead:

function Ctrl ($scope, $interval) {
    $scope.counter = 0;

    $interval(function () {
        $scope.counter++;
    }, 1000);
}

As the previous approach, this will propagate the counter updates to the view. I recommend using Angular’s services wherever this is possible and seems appropriate to the case at hand. However, always keep in mind that such services invoke $apply for you behind the scenes.

Hope you enjoyed this Sunday’s little reading! πŸ™‚

Setting up a Node Server and Securing it with SSL on RaspberryPi

RaspberryPis are awesome little things that you can do a lot of cool stuff with. Basically, a RaspberryPi (RasPi) is a 35 dollar, mini computer. It has LAN, USB, audio, RCA, HDMI and power ports as well as an SD card input. The A model has a 700 MHz processor and 256 MB of RAM. An SD card is flashed with an operating system and used on the device, there are lots of operating systems to choose from, I personally prefer Debian Wheezy. I purchased my RasPi some time last year and have had quite some fun with it since. When I first got it, I set up XBMC on it and used it as a humble HTPC or at least as a video media outlet in my apartment.

WP_20140531_19_52_36_Pro

Recently, I decided to use my RasPi for something far more awesome. I decided to set up a publicly secure node server on it and have it control an AR Drone in my apartment through REST calls (I don’t have any drone just yet though). In the following tutorial, I will show you how to set up a secure node server on your own RasPi and make it accessible from anywhere in the world.

First things first: Install Node

The first step is to install node on your RasPi. Power up your RasPi, log in as root user and then simply type the following commands:

wget http://nodejs.org/dist/v0.10.2/node-v0.10.2-linux-arm-pi.tar.gz
tar -xvzf node-v0.10.2-linux-arm-pi.tar.gz

This will download node and unzip it for you. If you then type ls you’ll see that node-v0.10.2-linux-arm-pi was unzipped successfully in your current folder. The next step is to set node in your global path so you can start it from anywhere. Type the following:

NODE_JS_HOME=/home/pi/node-v0.10.2-linux-arm-pi 
PATH=$PATH:$NODE_JS_HOME/bin

The node packet manager (npm) comes bundled with node, we will use that to install external modules. Node and npm should now be accessible from any location in your RasPi.

Install External Node Modules

You may need to install node’s native build tool for future use, to do that, simply type:

npm install -g node-gyp

The node-gyp build tool is now installed and located at:

%HOME%/node-v0.10.2-linux-arm-pi/lib/node_modules

You will find all future installed modules located in this folder. Next up is to install express (we will use this module to create our secure node server later on):

npm install -g express

It may be a good idea to install the socket.io module as well for future use:

npm install -g socket.io

We now have all the external modules that are needed.

Change from Dynamic to Static Local IP for the RaspberryPi

Since the aim is getting the RasPi accessible from the outside world, you need to have a static IP for it. Chances are you are using a router, and thus a dynamic IP is provided to your RasPi by the router. In this case, you need to make the dynamic IP static. You can start by typing the following command:

ifconfig

Note the fields inet addr, Bcast and Mask. Here is an example:

inet addr:192.168.1.110  
Bcast:192.168.1.255  
Mask:255.255.255.0

Now type the following command:

route -nee

Note the field Gateway, which is the IP of your router:

Gateway: 192.168.1.1

Now type the following command:

nano /etc/network/interfaces

Change the line iface eth0 inet dhcp to iface eth0 inet static. Now, change the information to include the following:

iface eth0 inet static
address 192.168.1.110
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1

Save changes made to this file and then exit (CTRL+X, Y and Enter). Now reboot your RasPi in order for the changes to take effect:

reboot

Log in as root user. That’s it, your RasPi now has a static local IP. In this example, the IP is 192.168.1.110. The next step is to port forward your global IP to this IP.

Port Forward Global IP to the RaspberryPi Static Local IP

In order to access the RasPi from the outside, we need to port forward our global IP to the RasPi static local IP. I prefer to use the router UI for this, I use a Linksys WRT54G router, here is a screenshot of how I do the port forwarding using this router:

Capture

Once you’ve done port forwarding, the RasPi should now be accessible from the outside.

Generate a Certificate Signing Request (CSR) for SSL

We need to generate a Certificate Signing Request (CSR) to sign the SSL certificate that we will use for the RasPi node server. We will use *cough* OpenSSL *cough* to generate the CSR, if OpenSSL is not already installed in your RasPi then simply install it by typing the following command:

apt-get install openssl

Now generate the CSR like so:

openssl req -nodes -newkey rsa:2048 -keyout private.key -out server.csr

Note: private.key is the private key which is for your eyes only, make sure to move it to a secure location. We will use this key later along with the SSL certificate to create the node server.

You will now get some questions that you need to answer, here is an example:

Country Name (2 letter code) [AU]: NO
State or Province Name (full name) [Some-State]: Oslo
Locality Name (eg, city) []: Oslo
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Salih AS
Organizational Unit Name (eg, section) []: IT
Common Name (eg, YOUR name) []: mysubdomain.mydomain.com
Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request

A challenge password []: 
An optional company name []:

Note: Email address, challenge password and optional company name can be left blank. The most important field here is Common Name, you need to type in the domain that you want to use for your RasPi. Setting up SSL requires a domain (unless you’re going for a mighty expensive and special SSL certificate), therefore you need to have one (in my case, I use https://raspi.sirars.com). You can purchase a domain at a good price from providers such as GoDaddy.

Generate the SSL Certificate

We will now generate an SSL certificate using the CSR we got in the previous step. An SSL certificate costs money. I personally prefer SSLs.com for their cheap price range, fast delivery and good documentation. I recommend that you order your SSL certificate from them. Once you’ve done that, edit the server.csr by typing the following command:

nano server.csr

Copy the entire content. Now go to this link and follow the steps thoroughly. When you’re done, you’ll get an e-mail from SSLs.com containing your SSL certificate (which has the name format mysubdomain_mydomain_com.crt).

Point Your Domain to the Global IP of the RaspberryPi

The next step is to point your domain to the global IP. Say that you own the domain http://raspi.domain.com, in that case you need to point this domain to the now global IP of your RasPi. I purchased my domain from GoDaddy, here is a screenshot showing how I pointed my subdomain to the global IP address of my RasPi using GoDaddy’s domain management panel:

Capture

@ points the whole domain, while subdomain raspi points to a specific IP. For security reasons, my IP addresses are censored in the screenshot. Once you’ve pointed either your domain or subdomain to the global IP of the RasPi, it will take around 10 hours or so to take effect depending on the domain provider.

Create Node Server Using the SSL Certificate

The last step, is to create the node server itself with the generated SSL certificate. Start editing the JavaScript file by typing:

nano node_server.js

Now create the secure server by inserting the following JavaScript code (make sure to use absolute file paths):

var fs = require('fs');
var https = require('https');
var privateKey = fs.readFileSync('private.key', 'utf8');
var certificate = fs.readFileSync('mysubdomain_mydomain_com.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('%HOME%/node-v0.10.2-linux-arm-pi/lib/node_modules/express');
var app = express();
var ip = "192.168.1.110";
var port = 443;          //HTTPS

app.get('/', function(request, response){
    response.send("Welcome to my RaspberryPi Node Server!");
});

var httpsServer = https.createServer(credentials, app);
httpsServer.listen(port, ip);
console.log('Node express server started on port %s', port);

This code simply creates the node server for you using the SSL certificate that was generated earlier. Note the usage of the static local IP. We also created here a simple GET request on “/” that returns a welcome a message to the user, so when the user types your domain name in the browser (which is basically doing a GET request, using HTTPS) he/she will be greeted by this message.

To start the node server, simply type the command:

node node_server.js

Test out your secure node server by visiting your domain using HTTPS, it should work by returning a welcome message. You can find my own server here.

Create a Script to Automatically Start Node Server on Boot (optional)

This step is optional but highly recommendable. Once you’ve finished setting up your secure node server, the next thing you want to do is to create a simple script that will automatically start up the server every time your RasPi is rebooted. Start editing the script file by typing the command:

nano startup_script.sh

Insert the following lines in the script:

NODE_JS_HOME=/home/pi/node-v0.10.2-linux-arm-pi
PATH=$PATH:$NODE_JS_HOME/bin
node /home/pi/node_server.js

Save the file and then exit. Make the file executable by typing the following command:

chmod +x startup_script.sh

Now, you need to move this script to the /etc/init.d folder:

mv startup_script.sh /etc/init.d

Reboot your RasPi, and the node server should now start automatically.

Hope you enjoyed this tutorial! I will do a second part soon explaining how this secure RasPi node server will control an AR Drone through REST calls. πŸ™‚

TypeScript Release Candidate

A release candidate version of TypeScript was finally released last week. New features have been added along the many bug fixes that were made. As of the Spring Update CTP2 for Visual Studio 2013, TypeScript is now fully supported making it a first class citizen. That means after getting the Spring Update CTP2, you won’t need to download TypeScript as a plugin to Visual Studio 2013. Notable features that have been added are simpler, more generic type declarations and order declaration merging of interfaces. Improvements to the lib.d.ts typings library have also been made, adding typings support for touch and WebGL development, making your life easier when working with HTML 5.

Generic Type System

The typing has been enhanced, making it more flexible. It is now possible to use any more freely, making type checking especially softer when working with inheritance. Consider the class Person that extends Human:

class Human {
    eyeColor: string;
}

class Person extends Human {
    eyeColor: any;
}

Giving the property eyeColor type any in the subclass was not possible prior to the RC version. Giving this possibility now, you are not forced to define the specific type found in the super class, which may be inaccessible at times. When it comes to generics, the same thing is possible. Consider the interface IPerson with a generic function and the implementing class Person:

interface IPerson<Value> {
    then<T>(f: (v: Value) => Person<T>): Person<T>;
}

class Person<Value> implements IPerson<Value> {
    then<T>(f: (v: Value) => Person<T>): Person<T>;
    then<T>(f: (v: Value) => any): Person<T> {        // This is also possible
        return undefined;
    }    
}

Declaration Merging Precedence

In addition, declaration merging of interfaces is now also possible. This makes precedence order easier when you work with external libraries. Say you have external interfaces IExternal with some functions:

interface IExternal {
    a1(): void;
    a2(): number;
}

interface IExternal {
    b1(): string;
    b2(): Date;
}

When these two interfaces are merged, they become this interface:

interface IExternal {
    b1(): string;
    b2(): Date;
    a1(): void;
    a2(): number;    
}

Notice the precedence order of the declared functions. Declaration merging is absolutely recommended, especially when you don’t want to change how the external libraries are initially referenced in your web application.

These are awesome features from the TypeScript team! I am happy that the community influenced the team to add these features, and I also would like to congratulate the team on reaching version 1.0. Well done! πŸ™‚

Directives in AngularJS

So I thought that I’d make a detailed post about directives in AngularJS. If you’ve just started out with AngularJS, chances are you are curious to learn about this powerful feature. Directives are great if you want to create your own custom HTML elements. In fact, directives give us a glimpse of the future. In HTML 5, we got new elements and the goal is to increase this in the future so you won’t need to use the class attribute so often. Learning to use directives may seem a bit complex for the AngularJS beginner, but trust me, it’s really easy once you get the hang of it. Using directives isn’t really mandatory when you work with AngularJS, unfortunately this leads to developers not using this feature. I hope to change that with my post, and make you use it if you don’t already.

A directive can be written in four different ways; as an element, attribute, comment or class. The best practice is to write it as an element or attribute. Here are the four ways a directive can be written in HTML:

<my-directive></my-directive>
<div my-directive></div>
<!-- directive: my-directive -->
<div class="my-directive"></div>

The directive is loaded into Angular at the start up of a web application. Usually in a bootstrap.js where you load your other Angular components, such as controllers and factories. The directive is loaded like such (line 2):

var myApp = angular.module('myApp', []);
myApp.directive('myDirective', myDirective);
function myDirective() {
    return ""
};

Note that in the HTML we called the directive my-directive, this is transformed to camel case and therefore we load the directive as myDirective in Angular. As you can see, this directive doesn’t do much. It simply returns an empty string. A directive function has up to eleven different attributes that can be used. It has priority, template, templateUrl, replace, transclude, restrict, scope, controller, require, link and compile. By no means will you be using all of those attributes at once, usually you would use three to four attributes depending on your web application. I’m going to give a short description of each attribute.

Priority defines the order of how the directives get compiled, this is the case when you have created multiple directives on a single DOM element. Directives with a greater priority number get compiled first.

Template is used to add your HTML template code that you want to be shown, and templateUrl is a URL to your HTML template.

Replace is used to either replace the directive element with your HTML template (true) or to replace the contents of it (false). This is by default set to false.

Transclusion is a sibling of the isolate scope (which I will explain soon), which means that it’s bound to the parent scope. This makes the content of your directive have its own private state. transclude can be set to true (transclude the content) or to ‘element’ (transclude the whole directive).

Restrict is used to define the type of your directive. It can be set to E (element), A (attribute), M (comment) or C (class). The default value is A.

By using scope, you can define an isolated scope for your directive content. If scope is not used, the directive will use the parent scope by default. Scope can be set to true (new scope created for the directive), false (use parent scope), pass in scope for two-way binding, pass in type and other custom attributes.

Controller is used if you want your directive to have its own controller. You simply set it with the name of the controller that you’ve loaded in Angular.

Use require if you want to have a dependency on other directives, in that case inject the dependency directive’s controller as the fourth argument in the link function (which we will get to shortly). require is set to the name of the dependency directive’s controller, if there are several dependency directives, then an array is used containing the controller names.

Link is used to define directive logic, it is responsible for registering DOM listeners and updating the DOM. Link takes in several arguments, and it is here where you define your directive logic. However, this attribute is unnecessary if you are using the controller attribute and got the directive logic inside a controller.

Compile is used to transform the template DOM. ngRepeat is an example of a template DOM that needs to be transformed into HTML. Since most directives do not transform DOM templates, this attribute is not often used. Compile takes in several arguments.

For more information on each of the directive attributes, I suggest checking the AngularJS documentation.

Time for examples of usage, let’s assume we have written the following directive in the HTML:

<my-directive></my-directive>

Now, in the JavaScript this directive is implemented like this (line 3):

var myApp = angular.module('myApp', []);
myApp.directive('myDirective', myDirective);
function myDirective() {
    return {
    restrict: 'EA',
    template: '<div>Hello World!</div>'
    }
};

I set restrict to 'EA' on purpose, to show you that you can make the directive implementation work on both an element and an attribute if you wish. This is a simple directive that returns a template div with the text “Hello World!”. Now, we can extract this template to a file:

function myDirective() {
    return {
    restrict: 'EA',
    templateUrl: 'helloWorld.html'
    }
};

And the content of helloWorld.html:

<div>Hello World!</div>

Let’s put our directive inside a controller:

<div ng-controller="myController"> 
<my-directive></my-directive>
</div>

The controller is simple, it looks like this:

myApp.controller('myController', myController);
function myController($scope) {
    $scope.message = "Hello World!";
};

Now, we change the directive:

function myDirective() {
    return {
    restrict: 'EA',
    template: '{{message}}'
    }
};

Can you guess what happens? The directive uses the parent controller and scope, and returns the message defined in the controller – “Hello World!”. Now let’s create a controller specifically for our directive, and call it myDirectiveController:

myApp.controller('myDirectiveController', myDirectiveController);
function myDirectiveController($scope) {
    $scope.directiveMessage = "Hello World!";
};

And change the directive to use this controller and an isolated scope:

function myDirective() {
    return {
    restrict: 'EA',
    scope: true,
    controller: 'myDirectiveController',
    template: '{{directiveMessage}}'
    }
};

Again, the directive will return the message “Hello World!”, this time from its own controller. If you want to pass parameters from the parent controller, that’s possible. Let’s assume that the parent controller myController has a messages collection, that we loop through in the HTML:

<div ng-controller="myController"> 
<div ng-repeat="message in messages">
<my-directive message="message"></my-directive>
</div>
</div>

We loop through the collection and pass each message to the directive. The directive then looks like this:

function myDirective() {
    return {
    restrict: 'EA',
    scope: {
    message: '='
    },
    controller: 'myDirectiveController',
    template: '{{message}}'
    }
};

The message is passed to the directive controller, by setting the message attribute in the scope to ‘=’. This can be done differently, you can type message="myMessage" in the div (instead of message="message"), in that case you need to add message: '=myMessage' in the scope. Using ‘=?’ means that a parameter is optional. Another thing you can do is send in type. You use the type attribute in the HTML, then add type: '@' in the scope.

Another thing you can do of course, is to use the link attribute to define your logic there. Let’s do that:

function myDirective() {
    return {
    restrict: 'EA',
    link: function(scope, element, attributes) {
        element.addClass('alert');
    }
};

Link takes in current scope as argument, the directive element itself and custom attributes that you can pass in. Link uses jQuery Lite, a lighter version of jQuery. You can do jQuery operations inside of this function, in this case we are adding a css class alert to the directive element. You can do a lot of other different things with directives, for more I suggest checking out the AngularJS documentation.

I’ve explained most of what you need to know about directives. When you write directives, I recommend that you create controllers specifically for the directives. Put all logic in the controllers, and do not use the link function. Avoid jQuery operations and stick to pure Angular. That way you keep your code clean and nicely isolated. I hope that this gives you a good introduction to directives, and helps you get started using them. As you can see, it’s not that hard, is it? πŸ™‚

When Two Forces Meet (AngularJS, TypeScript)

AngularJS is largely growing in popularity among front-end developers. According to a JavaScript developer survey conducted in 2013, it was shown that AngularJS was among the top two most used JavaScript frameworks. In a world where there are close to 17 million MVC JavaScript frameworks, this puts AngularJS on top of the game. On the other end of the scale, while not as widely used as AngularJS, TypeScript is slowly becoming the de facto compiler language for writing object oriented JavaScript. So what happens when these two forces meet? A great power emerges! We learned from Uncle Ben (Spider-Man movie) that with great power, comes great responsibility. In this tutorial, I show how these two forces can be combined to produce an ultimate web application.

Capture

Setup

As a .NET developer, I use Visual Studio 2013 and the TypeScript plugin for Visual Studio. This is what I recommend that you use unless you are for some reason against the Windows platform. Then using the NuGet packet manager, you can install the necessary AngularJS core files. In addition to this, make sure to install the AngularJS TypeScript definitely typed files which provides typed AngularJS components that can be used in your TypeScript code.

Bootstrapper

In AngularJS you create an app.js where you load your modules, controllers, factories and directives. You do almost the same thing in TypeScript, the only difference here is that your controllers, factories and directives are represented as TypeScript classes in an app.ts file. So your app.ts can look like this:

var appModule = angular.module("myApp", []);

appModule.controller("MyController", ["$scope", "MyService", ($scope, MyService)
    => new Application.Controllers.MyController($scope, MyService)]);

appModule.factory("MyService", ["$http", "$location", ($http, $location)
    => new Application.Services.MyService($http, $scope)]);

appModule.directive("myDirective", ()
    => new Application.Directives.MyDirective());

Note the usage of lambda, we do this to reserve lexical scope. Always make sure to use this instead of function() in TypeScript. Now that you’ve set up your bootstrapper, in the next sections we’ll look at how the individual AngularJS components are written in TypeScript.

Controller Classes

Controllers are written as classes, so your MyController.ts class can look like this:

module Application.Controllers {

    import Services = Application.Services;

    export class MyController {

        scope: any;
        myService: Services.IMyService;
	    data: any;
		
        constructor($scope: ng.IScope, myService: Services.IMyService) {
            this.scope = $scope;
            this.myService = myService;
	        this.data = [];
        }

        private GetAll() {
            this.myService.GetAll((data) => {
                this.data = data;
            });
        }
	}
}

Factory Classes

Similarly, factories or services are written as classes. So your MyService.ts class can look like this:

module Application.Services {

    export interface IMyService {
        GetAll(successCallback: Function);
    }

    export class MyService {

        http: ng.IHttpService;
        location: ng.ILocationService;

        constructor($http: ng.IHttpService, $location: ng.ILocationService) {
            this.http = $http;
            this.location = $location;
        }

        GetAll(successCallback: Function) {
            this.http.get(this.location.absUrl()).success((data, status) => {
                successCallback(data);
            }).error(error => {
                successCallback(error);
            });
        }
	}
}

Note the interface IMyService here. Always use interfaces to abstract your classes in TypeScript, just as you would usually do in a typed language.

Directive Classes

Directives are also written as classes. So your MyDirective.ts class can look like this:

module Application.Directives {

    export class MyDirective {

        constructor() {
			return this.CreateDirective();
        }

        private CreateDirective():any {
            return {
                restrict: 'E',
                template: '<div>MyDirective</div>
            };
        }
    }
}

Databinding with Alias

Finally, to be able to use your TypeScript classes from your HTML, you need to databind using alias. So your HTML can look like this:

<html data-ng-app="myApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
	<div data-ng-controller="MyController as mc">
		<div data-ng-repeat="element in mc.data">
			<label>{{element}}</label>
		</div>
		<my-directive></my-directive>
	</div>
</body>
</html>

Databinding without Alias

Unfortunately, databinding with alias does not work in Internet Explorer 8. Neither do directive elements(!). To make it work in IE 8, you need to change your HTML so it looks like this:

<html xmlns:ng="http://angularjs.org" id="ng-app" data-ng-app="myApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if lte IE 8]>
            <script>
                document.createElement('ng-include');
                document.createElement('ng-pluralize');
                document.createElement('ng-view');
                document.createElement('my-directive');
                document.createElement('ng:include');
                document.createElement('ng:pluralize');
                document.createElement('ng:view');
            </script>
            <script src="libs/es5-shim/es5-shim.js"></script>
            <script src="libs/JSON/json3.js"></script>
        <![endif]-->
</head>
<body>
	<div data-ng-controller="MyController">
		<div data-ng-repeat="element in data">
			<label>{{element}}</label>
		</div>
		<my-directive></my-directive>
	</div>
</body>
</html>

Now if you want to call your TypeScript class methods from your HTML in IE 8 without an alias, then you need to hook your methods (and everything else they use) onto the Angular scope. This can be done like the following, in MyController.ts:

module Application.Controllers {

    import Services = Application.Services;

    export class MyController {

        scope: any;
		
        constructor($scope: ng.IScope, myService: Services.IMyService) {
            this.scope = $scope;
            this.scope.myService = myService;
			this.scope.data = [];
			this.scope.GetAll = this.GetAll;
        }

        GetAll() {
            this.scope.myService.GetAll((data) => {
                this.scope.data = data;
            });
        }
	}
}

Notice how everything is hooked onto scope. That way, databinding is correctly achieved in IE 8, and you are able to call your GetAll() method from the HTML by simply typing GetAll() without alias.

Hope you enjoyed this tutorial! I’m planning on holding a workshop about this and doing TDD at this year’s Norwegian Developers Conference 2014, so make sure to book your tickets! πŸ™‚

Anonymous Functions in JavaScript are Evil

Anonymous functions in JavaScript can cause a lot of headache and pain. If you want to write testable JavaScript, you will spend days scratching your head to find a way to assert logic that resides in an anonymous function. The problem is that we have no control over what happens inside the anonymous function, unless we stub the sucker out and choose whatever happens after the function is called. But that’s not really a smooth way to do it, is it? There are ways to get around this issue, but some of them are messy in my opinion. There isn’t really a perfect way to do it, but I will show you two different ways that I know are possible.

Consider studentsController.js which has a function getStudents() that calls an injected service studentService:

var getStudents = function() {
    var _this = this;
    this.studentService.getAll(function (data) {
	_this.handle(data);
    });
};

We are testing the getStudents() function, how do we assert that the handle() function was called or that the data was updated correctly? It’s happening in an anonymous function call.

“Testing hooks”

One way to do it is to use so called “testing hooks”. This is in my opinion a messy way, since you have to insert code into the logic just to handle testing. What is possible however, is to make a post script that removes all testing hooks prior to production release. That’s still extra work to do though. You attach a hook onto the studentService.getAll() function like the following (line 6):

var getStudents = function() {
    var _this = this;
    this.studentService.getAll(function (data) {
	_this.handle(data);
    });
    arguments.callee.anonymous = this.studentService.getAll;
};

Now, in your test you need to call getStudents() once. Then you can control the data that goes inside the anonymous function like so:

getStudents.anonymous(data)

Stubbing Your Way Down the Dependency Rabbit Hole

Another possible way is to literally stub your way down the dependency hierarchy and spy on dependencies that get called. This is a painful way. You need an API to create fake objects, assume that we use Jasmine. In this case, you mock an object – http – in your test that gets called by studentService.getAll(), like so:

var httpObject = jasmine.createSpyObj('http', ['get']);
httpObject.get.andReturn("data");

Then you call getStudents() once and expect that the mock was called:

expect(getStudents()).toBe("data");

There are probably other ways to get around this, but I have found that option one is the simplest way. I’m also quite comfortable with it, as long as those hooks get removed pre-production. πŸ™‚