Angular Dependency Injection

I just spent two awesome days at ng-conf 2014 where were presented with a challenge to improve upon the already awesome Angular dependency injection. At first I didn’t really have any ideas. “The only way to improve the DI framework would require interfaces,” I thought. And I left it at that.

My subconscious mind, however, kept working on it and I woke up at five this morning with a few ideas. I admit that this solution needs some improvement, but I thought I’d at least write it down and see what comes of it.

One of the few weaknesses that Angular has in its dependency framework is because JavaScript lacks interfaces. This doesn’t mean however that Angular couldn’t build an interface system. I’m not sure if these ideas could be used without a framework like Angular, so I write this document with the understanding that it would naturally fit into Angular.

Before I begin, I should explain a little about how I personally use Angular, and more importantly, how the various pieces used in Angular come together to help the code stay organized. When I finally convinced my employer, to use Angular, the first thing we found is that it was very easy for everyone to have their own way to structure their code. It is for this reason that I came up with a coding standard that we now currently use.

There is, obviously, nothing in Angular that enforces this standard and I’ve seen a lot of good code that does it differently, but this is what makes most sense to me.

As you know, under the hood services and factories are the same thing in Angular. While I see no reason for this to change, I try to keep them and their purposes logically separated.

Factories:
A factory is used only when dealing with things that need to be created or saved. In general this means that they use $resource (or sometimes $http) to interact with our API. Controllers never directly interact with a factory, rather they are always used by a service. Factories always have the postfix, “Factory”.

Services:
A service is used to keep logic for a certain thing together. This helps with code reuse and to keep the size of a controller to a minimum. Services are used directly from controllers and other services. Often services use factories to get or save off data. Services are always prefixed with a dollar sign and a two letter abbreviation for the company or project it is used for. (Example: If I’m building a task app called Task App a users service may be named: $taUsers.

With that out of the way, I’ll explain what I think could be a good idea for Angular. I hope that there are others who can improve upon this because it has some spots that are a bit clunky.

I consider myself pretty new in the software engineering world, but when I think of dependency injection I think of interfaces. Most of my knowledge about DI is colored by the C# dependency injection framework: Windsor. The general principle that Angular lacks when it comes to dependency injection is that there can be more than one dependency that meets the requirements of the dependency. The particular implementation used is usually chosen at runtime based on the DI frameworks configuration. The only problem is that to do this correctly: there really needs to be interfaces, or something that acts like an interface, in JavaScript. I’m not sure what the best practice would be for declaring the members of an interface, but this is one idea. (Using ECMAScript 5.)

For “Pet Application” this would be used to create an interface.

1
2
3
4
5
6
app.interface('iAnimalService', {
  species: angular.STRING,
  commonName: angular.STRING,
  numberOfLegs: angular.NUMBER,
  speak: function(duration){}
});

Implementing the interface.

10
11
12
13
14
15
16
17
18
app.service('$paDog', function(){
  angular.implements('iAnimalService', this);//will throw an error if the requirements are not met
 
  this.species = “Canis lupus”;
  this.speak = function(duration){
    //…
  }
  //etc.
});

You can see that the $paDog service implements the iAnimalService interface and that any derivation from the contract will cause an error to be thrown.

I hope that this was helpful. I would love to hear feedback on this and how it could be improved or thoughts that others have.

How to Add a Widget to your WordPress Blog

My awesome wife asked me to do her a favor, “Can you write a tutorial on how to add an HTML widget to a WordPress blog?”

While I’m sure that there is already probably fifty explanations on how to do it, but well, I’ll write it anyway:

Step One: Smile. Think to yourself, “This is easy. I can do this.”

Step Two: Open your WordPress Admin page.

Step Three: Navigate to Appearance > Widgets

Step D: Select the widget type you want. If you’re doing an HTML widget, select “Text: Arbitrary text or HTML”

Step E: Drag the button to the sidebar (you may have more than one) that you want to have the widget on.

Step F: Stop worrying about the fact that I changed my enumeration system half way through.

Screen Shot 2013-10-28 at 9.17.38 PMStep G: Expand the widget editor by clicking on it and editing the title (optional) and the body of your widget (see image).

Step H: Click Save.

Step I: Check your changes by navigating to your blog.

Step J: If there are changes you want to make, go back to Step One, skip Step D, and continue until you have the widget in the way you want it.

Step K: That is it.

AngularJS Testing with Karma and Jasmine

AngularJS-Shield-largeAngularJS is the best thing to happen to JavaScript since jQuery. It’s what JavaScript development has always wanted to be. One of the key advantages to Angular is its dependency injection which is very advantageous when you want to unit test your code. There is one little quirk though… I can’t for the life of me find a tutorial out there that shows how to do that unit testing.

Sure there are recommendations: use the Jasmine test framework with the Karma test runner; but there isn’t a start to finish setup guide to make testing work. So I made one. I had to go all around the web finding out how to do this, which (if this is your first stop) you won’t have to do.

If you notice any errors please let me know, but as far as I can tell this is the best way to unit test Angular with Karma and Jasmine.

Introduction

This tutorial will lead you through installation of all the tools you will need to run automated tests using Karma and Jasmine. I don’t care if you’re doing TDD or TAD, but for this example, we’ll assume that you already have a file you want to test.

Install Karma

If you don’t have node.js installed, download and install it. After you have it installed go to your terminal or command line and type:

npm install -g karma

File structure

The file structure is irrelevant, but for these tests it will look something like this:

Application
| angular.js
| angular-resource.js
| Home
  | home.js
| Tests
  | Home
    | home.tests.js
  | karma.config.js (will be created in the next step)
  | angular-mocks.js

* I’m not advocating this file structure, I simply show it for example sake.

Configure Karma

Create a configuration file by navigating to the directory you wish it to be in and typing the following command in your terminal:

karma init karma.config.js

You’ll be asked a few questions including which testing framework you want to use, whether you want the files to be auto watched, and what files to include. For our tutorial we’ll leave ‘jasmine’ as the default framework, let it autowatch files, and include the following files:

../*.js
../**.*.js
angular-mocks.js
**/*.tests.js

These are relative paths that include 1) any .js file in the parent directory, any .js file inside of any directory inside of the parent directory, angular-mocks.js, and any file within any directory (located in the current directory) that is formated [name].tests.js (which is how I like to delineate test file from other files).

Whatever files you choose, just be sure that you include angular.js, angular-mocks.js, and any other files that you’ll need.

Start Karma

Now you are ready to start Karma. Again from the terminal type:

karma start karma.config.js

This will start any browsers you listed in the config file on your computer. Each browser will be connected to the Karma instance with it’s own socket and you will see a list of active browsers that will tell you whether or not it is running tests. I wish that Karma would tell you a summary of the last result of your tests for each browser (15 out of 16 passed, 1 failed) but alas for that information you need to look at the terminal window.

An awesome thing about Karma is that you can test on any device connected to your network. Try pointing your phone’s browser to Karma by looking at teh URL of one of the browser windows running the tests. It should look something like this: http://localhost:9876/?id=5359192. Point your phone, VM, or any other device with a browser to [your network IP address]:9876/?id=5359192. Because Karma is running an instance of node.js, your test machine is acting like a server and will send the tests to any browser that is pointed to it.

Make Basic Test

We are assuming that you already have a file to test. We’ll say that your home.js file looks something like this:

home.js

1
2
3
4
5
6
7
8
9
10
11
12
'use strict';
 
var app = angular.module('Application', ['ngResource']);
 
app.factory('UserFactory', function($resource){
    return $resource('Users/users.json')
});
 
app.controller('MainCtrl', function($scope, UserFactory) {
    $scope.text = 'Hello World!';
    $scope.users = UserFactory.get();
});

Inside of home.tests.js we can create our tests cases. We’ll start out with the simpler of the two: $scope.text should equal ‘Hello World!’. To test this we must mockout our Application module and the $scope variable. We’ll do this in the Jasmine beforeEach function so that we’ll have a fresh controller and scope at the beginning of each test.

home.tests.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'use strict';
 
describe('MainCtrl', function(){
    var scope;//we'll use this scope in our tests
 
    //mock Application to allow us to inject our own dependencies
    beforeEach(angular.mock.module('Application'));
    //mock the controller for the same reason and include $rootScope and $controller
    beforeEach(angular.mock.inject(function($rootScope, $controller){
        //create an empty scope
        scope = $rootScope.$new();
        //declare the controller and inject our empty scope
        $controller('MainCtrl', {$scope: scope});
    });
    // tests start here
});

You’ll see in the code example that we are injecting our own scope so that we can verify information off of it. Also, do not forget to mock out the module itself as on line 7! We are now ready to do our tests:

home.tests.js

15
16
17
18
    // tests start here
    it('should have variable text = "Hello World!"', function(){
        expect(scope.text).toBe('Hello World!);
    });

If you run this test it should run in any browsers looking at Karma and pass.

Make $resource Request

Now we’re ready to test the $resource request. To make this request we need to use $httpBackend with is a mocked out version of Angular’s $http. We’ll create another variable called $httpBackend and in our second beforeEach block we’ll inject _$httpBackend_ and assign the new variable to _$httpBackend_. We’ll then tell $httpBackend how to respond to requests.

10
11
        $httpBackend = _$httpBackend_;
        $httpBackend.when('GET', 'Users/users.json').respond([{id: 1, name: 'Bob'}, {id:2, name: 'Jane'}]);

And our tests:

home.tests.js

20
21
22
23
24
    it('should fetch list of users', function(){
            $httpBackend.flush();
            expect(scope.users.length).toBe(2);
            expect(scope.users[0].name).toBe('Bob');
        });

All Together

home.tests.js

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
'use strict';
 
describe('MainCtrl', function(){
    var scope, $httpBackend;//we'll use these in our tests
 
    //mock Application to allow us to inject our own dependencies
    beforeEach(angular.mock.module('Application'));
    //mock the controller for the same reason and include $rootScope and $controller
    beforeEach(angular.mock.inject(function($rootScope, $controller, _$httpBackend_){
        $httpBackend = _$httpBackend_;
        $httpBackend.when('GET', 'Users/users.json').respond([{id: 1, name: 'Bob'}, {id:2, name: 'Jane'}]);
 
        //create an empty scope
        scope = $rootScope.$new();
        //declare the controller and inject our empty scope
        $controller('MainCtrl', {$scope: scope});
    });
    // tests start here
    it('should have variable text = "Hello World!"', function(){
        expect(scope.text).toBe('Hello World!');
    });
    it('should fetch list of users', function(){
        $httpBackend.flush();
        expect(scope.users.length).toBe(2);
        expect(scope.users[0].name).toBe('Bob');
    });
});

Tips

  • Karma will run all tests in all files, if you only want to run a subset of tests change describe or it to ddescribe or iit to run the respective tests. If there are tests that you do not want to test change describe or it to xdescribe or xit to ignore that set of code.
  • I would also suggest reading through the Jasmine documentation to know what methods are available to you.
  • You also have the option to run your tests in an html file on the page. The code for our example would look something like this:

    home.runner.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Partner Settings Test Suite</title>
        <!-- include your script files (notice that the jasmine source files have been added to the project) -->
        <script type="text/javascript" src="../jasmine/jasmine-1.3.1/jasmine.js"></script>
        <script type="text/javascript" src="../jasmine/jasmine-1.3.1/jasmine-html.js"></script>
        <script type="text/javascript" src="../angular-mocks.js"></script>
        <script type="text/javascript" src="home.tests.js"></script>
        <link rel="stylesheet" href="../jasmine/jasmine-1.3.1/jasmine.css"/>
    </head>
    <body>
        <!-- use Jasmine to run and display test results -->
        <script type="text/javascript">
            var jasmineEnv = jasmine.getEnv();
            jasmineEnv.addReporter(new jasmine.HtmlReporter());
            jasmineEnv.execute();
        </script>
    </body>
    </html>

Story Estimation

dogsI’ve come up with the perfect explanation for how I would estimate stories.

First, we are not measuring time or complexity—we’re measuring effort.

For this example forget all you know—or think you know. Let’s ignore everything about T-shirt sizes or hours… instead we’ll think about vicious canines and the effort it requires you to render them unconscious in order to stop an attack.

Escaping a chiwawa (not Phil’s, I’m sure they’re nice and not vicious and we don’t want to hurt them) doesn’t require much effort at all. You have no fear to simply bend down pick it up and (as gently as possible) toss it a few feet away—out cold.

Escaping a mastiff (you initially thought was a horse), however, requires a significantly larger about of effort. I don’t want one of those sicked on me. You may resort to running, kicking, or beating him with a stick…it still may be attacking you.

Who is providing the effort makes a difference. If Dave, significantly stronger than I am, was knocking out the mastiff, he would perform an elegant taekwondo chop to the poor beasts skull and the attack would be over and out cold. Me, even if I used the biggest stick I could carry, it would still take significantly longer to render the dog unconscious.

The actual effort required to halt the attack is the same in each case for each of us, the dog needs to be knocked out—same problem same amount of effort.

The chiwawa is the story that requires the least amount of effort we have. The mastiff swallowed several chiwawas he thought were burritos—an epic with a LOT of effort.

My Three Dollar Phone Plan

I get all the phone calling, data, and text messages for $3 a month.

Theres a catch, right? I’ve got an awful phone or terrible service, right? To answer that, I’ll be upfront and say that my phone plan isn’t for everyone—but, just to be clear I have a great phone and my service is fine. Without further ado I’ll get into the details of my awesome phone plan.

Summary

My GSM phone has no SIM card. I don’t need one. I don’t subscribe to any carriers service (no Verizon, AT&T, T-Mobile, or Sprint for me). I spend the greater part of every day within range of either my work’s WiFi or my home’s WiFi. And I have a mobile hotspot for any time I’m driving, at the store, or not in range of a WiFi signal for some other reason. I do all of my calling over WiFi using a special app that uses my Google Voice phone number.

Details

My $3 a month plan is possible for these reasons:

  • Google Voice
    • A service that uses a singe phone number to ring all or part of your phones at once (home, work, mobile). I have a Google Voice Phone number (a ported Sprint phone number) and another provided by Google. (I only needed one, but too many people have both numbers so I opted to keep both phone numbers).
  • Google offeres free calling to anywhere in the USA or Canada over Google Chat
  • GrooVe IP
    • An Android App that utilizes Google Voice over Google Chat to offer VOIP calls over your phones network (WiFi or mobile). They have both a paid version and a free version. (They also have an app they have if you do choose to use a carrier that will change your call settings between using GrooVe IP and your carrier called GrooVe Forwarder based on your location.) As long as you have Google Voice and rout calls to Google Chat, all you have to do is log in and you’re good to go.
  • FreedomPop
    • If not for FreedomPop I would only get calls when I was near a WiFi signal. FreedomPop allows me to take a WiFi hotspot with me.
    • They may have a stupid name, but they offer free mobile internet. You get 500 MB of data without any charge. If you go over this amount you pay a very reasonable 2¢ per megabyte (or 1¢ per megabyte if you go with one of their paid plans). You can even get more free data by connecting to other friends who use FreedomPop or completing advertising offers (which they thankfully don’t cram down your throat). In the time I’ve been using it, 500 MB has been about two to three times as much data as I need.
    • FreedomPop will however throttle your data unless you pay them not to. This is where the $3 a month comes in.
    • They also don’t have to widest area of coverage currently. It mostly surrounds big cities, however this should all change around March of 2013 when they will be extending their network using Sprint 3g/4g LTE in addition to Clear Wire 4g LTE.

So there you have it. I get free calling through Google Chat routed to my phone via GrooVe IP (with a one time charge of $4.99) and pay an on going $2.99 charge to FreedomPop for 500mb of un-throttled data when I’m out of range.

Emergency Calling

Any phone regardless of whether it is activated will make emergency calls (911, 211, 112, 999, IXII depending on your country). There doesn’t even need to be a SIM card for this to happen. So even if you don’t have a WiFi signal for some reason, unless you are out of range of any networks that could work with your phone, you can still contact emergency personell.

Pro Quos

  • My phone always says that I can only make emergency calls, however, this is not the case and whether I use the phones dialer or GrooVe IP’s I get connected just fine.
  • I have to keep track of two devices. My Nexus 4 and my WiFi hotspot. I have to keep them both charged. Turn the hotspot off when I don’t want to use it (it only has about 6 hours battery charge).
  • Android also doesn’t nor have I found a 3rd party app that will allow you to priorities your WiFi networks. This means if I forget to turn my hotspot off at home then I’m using the data off of it (not that I mind, like I said earlier: 500 mb is more than enough for me).
  • Call quality, though usually good, is dependent on your network. If you have a slower internet connection, chances are your call quality could suffer. Keep in mind also, that typically upload speeds are lower than download speeds for many ISPs so even if you can hear the call just fine someone on the other end may not hear you at all. Chances are if you have a fast internet connection then your call quality should be just fine.

I should also point out that Google and Dish Networks are discussing the potential of a wireless network partnership. According to some sources this is all but done and should be rolling out toward the end of 2013, and while I don’t usually hold a lot of stock in rumors I would bet this one is fairly accurate. So there may be another option in the future regarding mobile data.

What kind of things have you done to lower your phone bill?