The Code Dump

A place a coder rants at...

Should You Use Angular 2.0 or 1.x?

| Comments

This question might seem trivial, but I keep seeing it pop up again and again everywhere in the Angular community. With all respect to the maintainers, they’ve managed to confuse quite a lot of smart people with this.

If you’re new to this world and want to get started with a new project you might have wondered whether you should use 1.x or “jump straight” to Angular 2. On the other hand, if you’ve already got Angular experience you’re probably getting worried about the impending changes and wondered whether you should start adapting to it.

And those are valid questions. After all, what are you supposed to think when every newsletter and forum are filled with articles about Angular 2’s forms, architecture, new router, Typescript, etc.? Why would the community push out so many articles about writing simple apps in Angular 2 if it shouldn’t be used?

The executive summary: There’s no Angular 2 to use, so Angular 1 is still the way to go.

A bit more details

Angular 2 is getting a lot of hype and attention, but the reality is that it is still in alpha and changes quite rapidly. It is not intended at all to be used in production yet. So, really, you can’t and shouldn’t start your company’s next big project using it.

So what’s up with all the articles? It’s a combination of a lot of things.

First, people are excited because Angular 2 brings a lot of nice stuff, and so they start exploring it and writing about the benefits.

Furthermore, it is impossible to be in this community and not hear people mumble about the Angular 2 migration that “will break all our code”. This motivates a lot of people to start learning 2.0 to see what is awaiting us and start understanding what’s going on.

Also, because it’s still heavily under development, writing about its current state and complaining about things actually might change things for the better as opposed to the general useless complaining we’re used to on the internet. It is a rare opportunity to affect technology you might be using for years to come.

All this is just to say that while Angular 2 is getting a lot of hype (and probably will get even more before it’ll be out), it is not production ready. If you have the time or freedom and find it interesting, of course you should give it a try, and even if you don’t have time it’s probably a good idea to keep up with the news and reading material. Eventually, the migration path will start getting clearer and when it does you’ll probably want to know as early as possible what you should be changing.

How will you know when to it’s time to start seriously looking at Angular 2?

If you’re reading this post, I’m assuming you read the news every once in a while. So just make sure to keep doing it. There are plenty of communities and newsletters (cough like the one here on my blog cough) you can trust to update you.

Happy Angularing!

Simple pagination and URL params with ui-router

| Comments

ui-router rocks. There’s a reason it’s become the de facto router in Angular. Its power is in its versatility, but it takes time to master all the different knobs it has to offer.

This shortie post is about something we face quite often: adding simple query parameters to our SPA for stuff like pagination and sorting.

Problem definition

The use-case is straightforward: say you have a long list of information that you’d like to present with pages and different sorting options.

The ideal case would be that our controller, let’s call it ListCtrl, has 2 optional parameters – page and sort– with default values (obviously 0 for pages and we’ll use upvotes for sorting).

Basically we’d like to have the following URLs be associated with the following parameters passed to ListCtrl:

  • /list with {page: 0, sort: 'upvotes'}
  • /list?page=1 with {page: 1, sort: 'upvotes'}
  • /list?page=2&sort=date with {page: 2, sort: 'date'}

This is really easy as pie:

State configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$stateProvider.state('list', {
    url: '/list?page&sort',
    controller: 'ListCtrl',
    controllerAs: 'list',
    templateUrl: 'list.html',
    params: {
        page: {
            value: '0',
            squash: true
        },
        sort: {
            value: 'upvotes',
            squash: true
        }
    }
});

You can see this looks like an ordinary state with a few details: we specify the names of our parameters in the url and provide those parameters’ default values and set them to squash, which means ui-router won’t put them in the URL if their current value is the default value (read all about this configuration in the docs of $stateProvider.

That’s about it!

Simple Controller

Our controller might look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function ListCtrl($stateParams, $state) {
    var self = this;
    self.page = parseInt($stateParams.page, 10);
    self.sort = $stateParams.sort;

    function sortList() {}
    function updatePage() {}

    sortList();
    updatePage();

    self.nextPage = function() {
        $state.go('.', {page: self.page + 1});
    };
    self.prevPage = function() {
        if (self.page > 0) {
            $state.go('.', {page: self.page - 1});
        }
    };
    self.sortChanged = function() {
        $state.go('.', {sort: self.sort});
    };
}

Note that ui-router’s parameters’ default values must be strings and are passed to us from $stateParams as strings, so we take care to use parseInt.

You can see that updating the URL parameters is quite straightforward – you just call $state.go with the current state ('.') and the parameters you want to update – the rest remain as-is!

Updating parameters with reloading the controller

The example above worked because $state.go() would reload our controller with updated $stateParams. While this might be all you need sometimes, other times you won’t want to reload the whole controller.

In those situations you can use $state.go() with the special {notify: false} configuration which effectively prevents your controller from being reloaded (see the documentation for full details). What it does mean, though, is that we’ll need to update sorting/paging ourselves in the controller:

1
2
3
4
5
self.nextPage = function() {
    self.page++;
    updatePage();
    $state.go('.', {page: self.page}, {notify: false});
};

That’s about it! You can download a really simple skeleton that shows how this works here.

Happy routing!

Using ng-change instead of $watch in Angular

| Comments

In the olden days, before you used MVC frameworks such as Angular, you were probably used to doing stuff like this in jQuery:

1
2
3
4
5
function showNameChanged() {
    // stuff...
}

$('input.show-name').change(showNameChanged);

This achieves the simple task of performing an operation whenever the user typed something inside an input, using JS change events.

In Angular, though, most people would consider this code the equivalent:

1
<input type=text ng-model=show.name>
1
$scope.$watch('show.name', showNameChanged);

Now, you might think I’m being nit picky here, but I’d usually rather write it like this:

1
<input type=text ng-model=show.name ng-change="showNameChanged()">

ng-change?

I’m always surprised that this directive is foreign for a lot of newcomers to Angular, and that $watch seems to be the tool everyone reach for first. ng-change is a simple directive that operates much like using jQuery to register a change event listener.

In my opinion, this is the “real” equivalent of the first code sample we saw.

The differences

  • Using ng-change would call our showNameChanged() function only on actual changes to the input by the user. Watches, as you might know, are called in other cases too: right when they’re being defined the first time and on changes made to the value not by the user, e.g. programmatically.
  • I’m a big believer in expressing intent when writing code (you do know The 4 Rules of Simple Design, right?). If my intent is to only listen to changes by the user, and I don’t expect the input to be changed programmatically, I would rather explicitly show that. Using $watch means whenever you read this code in the future you’ll have to consider whether it’s being triggered by something else, too.
  • Another plus for intent for ng-change is that you can see from the template that this input is bound to something and how. Otherwise you’d need to start looking for the value in ng-model in the controller for usages. This way you can see right away who’s listening for these changes.
  • Less code. And less code == less things to debug. As you can see above we didn’t need to add another line to the controller to listen for input changes.
  • Using ng-change is a tiny bit more performant, since it uses one less watch expression. Since Angular knows it should only call the expression on change events it doesn’t need to keep evaluating it on every digest cycle, as opposed to, well, a watch. Yes, just this one doesn’t matter a lot, but across a big app these things stack up.

Of course, sometimes $watch is what you want. But sometimes – it ain’t!

Happy coding!

AngularJS: Pitfalls using ui-router’s resolve

| Comments

If you’ve been doing Angular any amount of time, I hope you’ve found and started using the great ui-router library. It truly helps when building anything that’s larger than a simple project.

A really useful feature is resolves. It is ui-router’s way of letting us provide values to the different controllers it manages, in a way that makes them simpler – it hides asynchronous operations and so controllers are more linear.

For example, a controller that needs a specific goat might be written like so with vanilla Angular:

1
2
3
4
5
6
angular.module('app').controller('GoatCtrl', function(GoatService) {
    var self = this;
    GoatService.getGoat().then(function(goat) {
        self.goat = goat;
    });
});

But if this is a controller of a route defined by ui-router, we can use a resolve to hide the promise from it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
angular.module('app').config(function($stateProvider) {
    $stateProvider.state('goat', {
        url: '/goat',
        controller: 'GoatCtrl as goatCtrl',
        templateUrl: 'goat.html',
        resolve: {
            goat: function(GoatService) {
                return GoatService.getGoat();
            }
        }
    });
});

angular.module('app').controller('GoatCtrl', function(goat) {
    this.goat = goat;
});

The benefits, I assume, are clear: cleaner controllers, especially if you have multiple things that need fetching and less meddling with asynchronous code and promises.

But, as always, there are pitfalls and use cases where this solution comes short that you should be aware of in order to make the right decision.

The pitfalls

Might feel slow/laggy/stuck

You’ve had this happen to you many times (probably earlier today): you press a button which triggers a route change. If that route has a resolve that takes a few seconds to complete, you won’t get any feedback about anything happening until the resolves are resolved. This can be frustrating, making you wonder did I click it? Perhaps you’ll click again just to make sure.

In a resolve-less state, the new controller and template would start rendering immediately, which by itself provides some feeling of progress. I usually go for not using resolves in this case and have the controller show a proper loading state for itself. This way it doesn’t matter where you’re transitioning to this route from, you’ll still have the proper loading indication.

You can also, of course, have the button show some spinner or something until the route transition happens.

Errors happen in no-man’s-land

You have a resolve that makes an AJAX $http call. Eventually it will fail. Where will you handle the error? You don’t have a controller yet to manage things at this point.

Make sure to either have some generic error handling or make your resolves always return some value, even on errors, and then handle those situations in your controller.

It adds complexity to the code

Even though the solution makes some parts of the code clearer, like the example at the top of this post, it has a price. The dependencies of the controller are now pushed away to a place far far away. Some of the setup of the controller now happens in a different place, even though it is still very coupled – each resolve maps to an argument for the controller.

I don’t always like the effect this has on my code and if I notice that I have to keep flipping back and forth between the controller and the state setup I might decide to just push it all together (maybe using a helper service) to make things clearer and have them just sit together.

Take aways

Resolves can be very handy and I definitely use them, but it’s important to understand where they might clash with maintainability and UX and make sure to keep tabs on it.

Happy routing!

Don’t use $http’s .success()

| Comments

An example of performing AJAX requests in Angular is probably the second thing you ever saw when getting into Angular (right after an example showing off two way binding). It does look very sexy and easy when you look at it, since most examples look something like this:

1
2
3
$http.post('/products', product).success(function(createdProduct) {
    // w00t!
});

This is usually the first time you learn about promises in Angular and how they work. Later when you get more in depth you’ll realize that only $http’s promises have success() and error() functions, while regular promises just have then().

You might wonder what’s the difference, really. Well, Angular is all about decisions, and this time I want to stress how using success() is a bad one.

How success() is implemented

If we look in Angular’s source code here we can see that success is basically:

1
2
3
4
5
6
7
promise.success = function(fn) {
    // ...
    promise.then(function(response) {
        fn(response.data, response.status, response.headers, config);
    });
    return promise;
};

So it’s just like then() but deconstructing the response object. This is essentially just syntax sugar so you’d have a callback that gets the JSON object back as its first argument and save you reaching into response.data yourself.

The problem

First, I hate anything that creates inconsistency in my code. If we use success() we’ll still have to use then() in every other place that has a promise, which makes this syntax sugar more of a cognitive leak in my opinion than anything useful.

Second, it couples your code in a subtle way – you’re telling everyone you’re actually reaching to the network to get something.

Say we have a service for managing some resource:

1
2
3
4
5
6
7
angular.module('app').factory('ProductsService', function($http) {
    return {
        getProduct: function(id) {
            return $http.get('/products');
        };
    };
});

And this is used later like so:

1
2
ProductsService.getProduct(123).success(function(product) {
});

This means that all users of ProductsService definitely know that getProduct() goes out to the web to get data. What if you later add caching? What if you decorate ProductsService with some wrapper and need to chain the promise it returns? If everyone assume your promises have .success() it’s going to be a PITA.

What I like to do instead

On several projects with multiple teams we’ve found this idiom to be quite nice:

1
2
3
4
5
6
7
8
9
angular.module('app').factory('ProductsService', function($http) {
    return {
        getProduct: function(id) {
            return $http.get('/products').then(function(response) {
                return response.data;
            });
        };
    };
});

This way, we’re using promise chaining to hide the $http promise and hide response data except for the JSON itself (e.g. response headers, request config). This means that we later can easily swap the original promises with cached promises, or generate random data with a fake promise when testing. Suddenly no one cares about HTTP.

I’ve found that 99% of the time your callers don’t need/know how to handle HTTP errors anyway, so hiding it works. I prefer to go with generic error handlers where needed.

AngularJS: Dynamically loading directives

| Comments

It’s hard to write a webapp today without some sort of dynamic feed/list: Facebook’s news feed has photos, text statuses, ads, Twitter’s feed has promoted tweets, image tweets, retweets, and maybe you have a chat/messaging feed in your app with text, videos, photos and stickers.

While this is relatively common, it might not be straightforward to do so in Angular, or what is the Right Way™ for doing this.

The problem

Say that we get from a REST API a list of feed items, that look somewhat like this:

1
2
3
4
5
6
7
8
9
10
[
    {
        "type": "text",
        "body": "hello"
    },
    {
        "type": "image",
        "url": "http://..."
    }
]

Naively, we might say what we really want is to create 2 directives, one for rendering text items (text-feed-item) and one for images (image-feed-item), and write something that looks like this:

1
<div {{item.type}}-feed-item item=“item”></div>

Of course, this isn’t valid Angular code. So what should you do?

Keep it simple, stupid!

One of my main rules of thumb is to keep away from complexity as much as I can and be explicit. This means that if I have only a handful of different item directives to choose from, I’ll write something very explicit, like this:

1
2
3
4
<div ng-switch=“item.type”>
    <div ng-switch-when="text" text-feed-item item="item"></div>
    <div ng-switch-when="image" image-feed-item item="item"></div>
</div>

This has the several advantages:

  • Simple as can be
  • Explicit
  • Easily searchable (say, if you want to find who uses the image-feed-item directive you can use plain search and find this)

But, in case you have more than a handful of different feed item types this might get out of hand or just plain get annoying.

$compile

Angular’s way of dynamically adding directives to the DOM is compiling them. I know the word “compile” feels quite odd in our little corner of web development, but for some reason that’s the word they chose for the process of having Angular parse a DOM node and executing all the Angular goodness it requires.

Making a dynamic directive that does basically what our first naive attempt looked like isn’t that hard, once you know about Angular’s $compile service:

1
<div item-generator item="item"></div>
1
2
3
4
5
6
7
8
9
10
11
12
angular.module('myApp').directive('itemGenerator', function($compile) {
    return {
        scope: {
            item: '='
        },
        link: function(scope, element) {
            var generatedTemplate = '<div ' + scope.item.type
                + '-feed-item item="item"></div>';
            element.append($compile(generatedTemplate)(scope));
        }
    };
});

This will result in something that looks like this if you inspect the DOM:

1
2
3
4
5
<div item-generator item="item">
    <div image-feed-item item=“item”>
        <img ...>
    </div>
</div>

As you can see, $compile has two steps. First, we call it with the HTML we want to generate, which returns a function. We then call that function with the specific scope we want the generated element to have and then we actually get the new element that we can add to the DOM.

Yes, this is more complicated, requires being more comfortable with how Angular works and doesn’t have the benefits I listed above for the simpler solution, but sometimes this approach is necessary.

AngularJS: How to setup pushState with html5Mode

| Comments

One of the nice features of Angular is the built-in support it has to use “real” looking URLs such as /stuff/ instead of URLs with hashes/fragments, e.g. #/stuff (which we’ve gotten used to in the SPA world).

A lot of developers mess settings this up the first time. It is frustrating that it seems to work except in certain situations when set up bad (refreshing doesn’t work, or links are broken, etc.). But if you know what buttons to push: it actually just requires a little work on your Angular app and some configuration on your server side.

Client set up

First, you need to add a config() block to enable html5Mode like so:

1
2
3
angular.module('app').config(function($locationProvider) {
    $locationProvider.html5Mode(true);
});

This enables HTML5 mode in Angular. This mode means Angular will use the pushState API to change the browser’s URL without causing a reload when possible (if you’re using a legacy browser that doesn’t support it, Angular will automatically fallover to using hashes as always).

The second change on the client is to not have the hashes in your links. For example change <a href="#/stuff">Stuff</a> to <a href="/stuff">Stuff</a>.

And the last client change is to add to your index.html file, under the <head> section a <base> tag, e.g. <base href="/">. This tells Angular what is the base path of your app so it would know how to change the browser URL correctly. For example, if your Angular app’s root is under http://www.example.com/app, you should probably have a base tag set to <base href="/app/">.

Server set up

Essentially this depends on what server solution you have for serving Angular’s assets. You need to make it so that when the browser tries to access some “fake” URL, like /users/123, it would serve your Angular app. A lot of people first skip this step and then don’t understand why they get 404 errors when refreshing their apps.

Of course I can’t go over all the different server side technologies here, but as an example, here’s the basic nginx configuration:

1
2
3
4
location / {
    root /path/to/app;
    try_files $uri index.html;
}

This tells nginx to try and fetch the file at the URL. If it really exists (e.g. it’s a javascript file, an image, etc.) it would be served to the client. If it doesn’t exist we assume it’s a URL that Angular should manage and just return the index.html file to serve the Angular app and have it take over from there.

Happy state pushing!

AngularJS: Notifying about changes from services to controllers

| Comments

Once you write enough Angular code you (hopefully) start pushing off as much logic as you can from your controllers to services (note: I’m saying “services” as in the general concept, but technically these are usually factories).

Eventually you’ll stumble upon the need to have your services notify controllers about changes. You have a lot of options: passing callbacks from controllers to services, using $watch on shared data, promises, events, etc. A lot of us end up wondering what’s the best practice in this case?

In my opinion there’s one way that’s almost always better.

Pub-Sub using “hidden” events

Angular’s events mechanism ($on, $emit, $broadcast) is useful, but if you don’t use it just right it can quickly spiral out of hand. Also, causing memory leaks is remarkably easy. But, with right incantation we can use it to our advantage in quite a robust way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
angular.module('app').controller('TheCtrl', function($scope, NotifyingService) {
    // ... stuff ...
    NotifyingService.subscribe($scope, function somethingChanged() {
        // Handle notification
    });
});

angular.module('app').factory('NotifyingService', function($rootScope) {
    return {
        subscribe: function(scope, callback) {
            var handler = $rootScope.$on('notifying-service-event', callback);
            scope.$on('$destroy', handler);
        },

        notify: function() {
            $rootScope.$emit('notifying-service-event');
        }
    };
});

Win!

You can use this little snippet whenever you need to. It comes with these already bundled in:

  • It takes care of cleaning up after itself properly by listening for the $destroy event on the controller’s scope
  • It uses events only on the $rootScope using $emit which is more performant than using $broadcast (further reading if you’re interested)
  • It encapsulates the actual use of the events mechanism inside the service, which, IMO, makes for cleaner interfaces

Here’s a little jsfiddle that shows this in action.

AngularJS: What’s the difference between factory and service?

| Comments

When getting started with Angular it can be a bit overwhelming to try and make sense of all the different tools and types of components that are available to us.

A very popular example of this are Services and Factories: they seem so similar yet they both exist for some reason. You’re trying to understand whether there’s really any difference. No one wants to pick the “wrong one” or “make the wrong choice”.

Factories vs. Services

First, right off the bat I’ll say they’re pretty much equivalent. Why do we have them both, then? That’s for the gods of Angular to know. They both allow us to create an object that can then be used anywhere in our app.

Most important is to realize that both are singletons in your app, even though the name “factory” might imply differently.

Essentially, factories are functions that return the object, while services are constructor functions of the object which are instantiated with the new keyword.

To the code!

To the users of our services and factories it all looks the same. This code below would be written the same regardless of which was used:

1
2
3
angular.module('app').controller('TheCtrl', function($scope, SomeService) {
    SomeService.someFunction();
});

Here is a matching factory:

1
2
3
4
5
angular.module('app').factory('SomeService', function() {
    return {
        someFunction: function() {}
    };
});

This will result in an injectable object called SomeService with a single public function someFunction.

And here is a matching service:

1
2
3
angular.module('app').service('SomeService', function() {
    this.someFunction = function() {};
});

This will result in… well… the same injectable object as above.

What to do? Use factories!

Now that you know the difference and can see that there’s none really, I’d recommend just going with one and get on with coding. Which one? Factories are the popular choice in the Angular community. I went with this decision years ago and recently saw that it is also the recommended way according to John Papa’s (excellent) style guide.

Badass

| Comments

In our industry there are plenty of thought leaders, thinkers, authors. A lot has been written about the craft of making products – how to increase engagement, how to have better traction, improve your funnels, using gamification, blah blah blah.

Not a lot, though, focus their vision on the actual users of these products. Instead of putting so much effort into sucking more money and time from our users, always thinking me me me, it is remarkable to think about the users’ wellbeing. Is having people on your site for an average of 4 minutes per visit instead of 3 better? Shouldn’t we optimize our products so that they get the most value in the least amount of time?

Not a lot think like this. Kathy Sierra is one of the few, and is an exemplar of how we should strive to look at and treat our users. And more than just that, she has spent years learning so much about these things and articulating her learning so well that it would be a tremendous shame if we, as an industry, disregard this extraordinary opportunity to learn from her.

She has recently released her new book, Badass: Making Users Awesome, which is the best book I’ve read in years – hands down. I haven’t published a book review in my blog for over 4 years, this book was so good I had to sit down and write this (I’m actually working on some interesting AngularJS posts but decided this book is much more valuable for you guys). I’ve been very intrigued by her ideas for a while, since I’ve watched her talks that relate to much from the book, here and here. Watch those videos, then if you’ll go and read it now – you can stop reading this right here. Everything she wrote is better than the rest of this text.

Apps that make you fat

This glorious book is intended to help us understand how to make products that make their users better – make them badasses. To teach this, Kathy goes through so many wonderfully interesting topics where each chapter is worth the cost of the book by itself.

It starts with understanding how motivation works, why users would want learn how to do things and how we can use that to help them keep going and get better. This is under the viewpoint that if you actually help users be better and achieve things they truly want and care about you will have the best kind of marketing engine, which she calls WOFO – Word OF Obvious. If your product is that good, obviously they’ll spread the word.

Then we go into understanding expertise – badass-ness. What makes an expert an expert? What is the right way to become an expert in some context? Deliberate practice for building skills, perceptual exposure and other tools are introduced to help us guide users. But even if we put users aside, this is invaluable for anyone that still wants to keep getting better and learn new things.

Another interesting topic is cognitive resources and how our brain works. While this too is in the context of designing products to treat users optimally, it also shines a light into how we ourselves work. I suddenly realized why I do somethings that I do, became aware of habits and their causes, and understood how to better use them to my advantage.

It then goes on to explain how cognitive resources and will power are connected so that bad apps that make us work harder will eventually drain our will power so we won’t be able to say “no” to that piece of cake. This and more interworkings of the brain are fascinating in my opinion.

Really, go get it. It’s really packed with lots of interesting details, great business advice and even some life changing wisdom.