The Code Dump

A place a coder rants at...

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.

Bad Commit Messages Hall of Shame

| Comments

Too many of us just go through the motions with Git and other version control systems without dedicating enough thought to why we do the things we do. This kind of cargo cult programming is so common I don’t think I’ve seen a single team where this wasn’t the case for some of the members in it.

The Hall of Shame

  • “bug fix”, “more work”, “minor changes”, “oopsie”, “wtf” – These mean nothing. You may as well supply no commit message. Why did you even bother to write it?
  • “Work on feature blah blah” x 20 commits in a row – This is unfortunately aided by different IDEs and tools that suggest your previous commit message automatically. It creates a bunch of commits that are not discernible from one another. Yeah, I get a general topic of what they’re about, but we lost the ability to talk about them without using specific hashes and if you see that these changes for feature “blah blah” introduced a bug you have no easy way to guess which commit did it. You have to start going through the diffs.
  • “Fix BUG-9284” – Bug trackers can be awesome, and if your workplace uses them then it makes a lot of sense to write the ticket number in the commit message. The problem is that writing just that now means that if I’m looking at a commit and trying to understand why a change was done I now have to go to a different system and search that number in it. This is a hassle. I usually copy and paste some part of the description of the bug to the commit message to make it easier for anyone in the future to understand what this change does.
  • “Change X constant to be 10” – These commit messages are a lot like useless comments in code. When the description is just which changes were made it’s just duplicating the code – we can see the diff and see that X was changed from 5 to 10. What we can’t see is why this change was needed.
  • “super long commit message goes here, something like 100 words and lots of characters woohoo!” – Tools care about your commit messages. There’s a convention used by most git tools that prefers the length of the first line in your commit message to be 50 characters or less. Stick to it. It makes it easier to look at the history and means you intentionally put the really important bits in the top line.

Why are you even writing a commit message?

A lot of us got bad habits for commit messages when we first started using a VCS and didn’t understand all the benefits it has. Maybe you originally only worked alone or with a small enough team so that changes were trivial to all of you. But some day you’re going to add another developer that won’t be able to easily look at your cryptic commits and understand what was done. Or your memory will fail 2 years later when you stare at something and have no clue why you did it.

Commits are our aid in times of great need

When do we even look at the commit history?

I use git constantly when I’m in the mud and need help. Did I just notice that someone broke a feature? I’d rather be able to whip up the commit history and spot from the messages which one might be the bad one, instead of having to start searching every damn “BUG-4239” in the issue tracker and open the diff for each “minor changes” commit.

Also, if I’m lost about when something became borked I reach for my favorite tool – git bisect. But how can I easily know what range of commits to use if the last 50 commits were all called “Feature blah blah work”?

Lastly, I constantly rely on the history when making changes to code. I see a line I’m not sure about and I immediately fire up git blame in order to see in what commit it was added, what else was done along this line and, most important of all when done properly, read the commit message that hopefully tells me what I was trying to understand. If all I see is “move call to foo to be before call to bar” I’m hopeless – can I move it back? Was it moved because it broke something? Should all calls to foo everywhere be in this order? I now have to hope whoever committed this remembers why he did the change (pro-tip: or hope you have good tests, wink wink nudge nudge).

Write commit message with a purpose

Good commit messages follow these criterions:

  • They say why you did these changes.
  • They shortly describe what was done so we can effectively glance through the history and find what we need.
  • They are self-contained – It’s great that you have a bug tracker, but don’t make me have to open it to understand why a commit was made.
  • They are in present tense – no more “Fixing buy button disappearance on Mondays” or “Fixed buy button disappearance on Mondays”. The convention is “Fix buy button disappearance on Mondays”.

Repent now

No, you don’t need to delete your repository and start from scratch. Decide that from now on you’ll write commit messages with the attention they deserve. Talk with your team, agree on the guidelines for messages and publicly shame whoever disrespects you with bad commits – hey, it worked for continuous integration!

Testing the Untested

| Comments

I’m quite of a testing nut. TDD gave me a big leap forward in my career. I attribute to it a major part of my ability to tackle big tasks.

I won’t go into it again, you can read some of my thoughts about it here. As the years passed I must admit that I’ve become less of a zealot about this. Yes, I write some code without tests (gasp!). Especially when I crank out prototypes for clients to get fast feedback (after all, a good feedback loop is what TDD is all about).

But, even when I don’t write tests I still do it responsibly. Once the code reaches some stability (and this usually happens after a week or two of development, not months) I add tests as I go along.

This is incredibly important. How many times did you let a spike turn into a big ball of mud that is super hard to test? Having the discipline to act on time is a big part of being a professional.

How should you go about doing this? First, start covering the parts of the code that break the most or that you find hard/scary to change. This means we first add the tests with the biggest bang for the buck.

I tend to add test cases almost as if I were writing the whole thing from scratch in TDD. I’ll write many small test cases and they give me the confidence that everything is in order. I might delete some of these tests later, but this isn’t waste! Once you’re skilled in testing, writing a few more tests is cheap and worth it – even if you delete them two hours later.

An important thing here is to see your damn tests fail. The TDD cycle is red-green-refactor. If you haven’t seen a test fail, how can you tell it’s even working? You need to test your tests.

Yes, you already wrote the code, and so it makes sense that the test is passing. But the solution is stupidly simple: break the code. Find the conditional or whatever that this specific test is checking, change it so it’s invalid and see the test fail with your own eyes. That’s the only way to make sure that it works, checks what you meant it to check, and that the error it produces is decipherable.

Don’t test hard, test well :)

My checklist for upgrading to Angular 1.3

| Comments

Angular’s 1.3 version was released a few months ago. Of course that the moment it was out I tried it with one of the bigger projects we’ve been working on. And of course I saw that so many things were broken (due to dependencies that haven’t caught all the related bugs yet) and just reverted and decided to wait a bit for things to ripen.

A couple of weeks ago I upgraded our app to 1.3 without much trouble. Here are the steps I took to minimize risks of breaking things:

1 – Read Angular’s changelog and search for breaking changes

I opened Angular’s official migration guide and started going over the changes to look for things that we’d have to change in our code. Fortunately, we had very little changes to make in this step.

The only issue was with some change in the semantics of directives with replace: true which broke some of those for us and I had to essentially remove that flag from them. We don’t have a lot of these and for that I’m thankful – especially as they were just deprecated in this release.

2 – Research our dependencies

I went over the dependencies in our bower.json file and checked each:

  1. Check that there’s a new release that mentions Angular 1.3 compatibility
  2. Search the GitHub issues of the project for issues that mention 1.3
  3. Read the package’s changelog to see what breaking changes may have been made recently and update our code accordingly

3 – Update everything

This essentially means updating the values in our bower configuration and installing the new dependencies.

4 – Exploratory testing

I went over the different screens in our app and paid extra attention to making sure our dependencies still worked. For example, that the modals are displayed correctly and that the dropdown menus didn’t break.

In this step I discovered about 3 things that broke that I had to fix. The fixes were relatively straightforward – I opened up the project’s site and found out what was changed or that someone else already tackled these changes (a big advantage to waiting out a couple of months before upgrading).

5 – Run the tests

We have a nice suite of unit tests and some end-to-end tests. I ran them to make sure that everything is in order. To my surprise, these passed without a hitch, except for one small test that had to be fixed (it broke because of changes in ngModelController that affected the API we used for testing, but the feature itself didn’t break).

That’s it!

This was really less exciting and problematic than I feared it might be. I’m happy this went pretty smoothly and allowed us to get on with work and start enjoying the new improvements in Angular without having to waste too much time on the move itself.

Happy coding!

I take it back: Don’t read a book a month

| Comments

About 7 years ago I posted my first post on this blog – One Book A Month. In it I make the point of the importance of reading and constantly learning: the person that stops learning that stops living. I attribute a lot of my success to the fact that I constantly try to learn new things.

But, as with everything, it’s possible to push this too far. I’ve read around 20 books in 2014, listened to hundreds of podcasts and read countless blog posts. I never liked “wasting time” – not a lot of TV watching, not playing games, etc. Instead I had this urge to keep learning.

I recently realized that this habit has become busywork. I kept filling my time. Learning helps, but sometimes enough is enough.

What was I getting out of all of this learning?

After all, does it matter that I’ve read every book on technology X if I never use it? I can keep reading every post Amy Hoy wrote and swallow Just Fucking Ship in a day, but if I never ship what good is it? If I read 10,000 pages, but didn’t act – did I really read anything?

If you have to ship – ship, don’t read

I decided to actively spend less of my time consuming. Even though it is intellectual consuming and not time wasting per se, it sums up to the same result. I will focus more of my time to writing blog posts, side projects, etc. With this, I hope, I will build up once more a habit of shipping fast and often.

Will it make a big difference? Only time will tell, but I believe it will. And don’t get me wrong, I’ll probably still read a handful of books, since that really is my hobby, but I’ll treat it as a hobby and so will make sure it doesn’t eat up too many hours that could have been invested in laying out the bricks to getting myself someplace better.