Building VTS

The Official VTS Engineering Blog

Promise Like a Kid

By Gustavo Matias

A promise is simply a way to handle responses from an asynchronous request. An example I really have fun imagining is when I was a kid, whenever my mom and I would go grocery shopping, I would beg her to buy some of my favorite cookies.

However, with one condition. She would allow me to run to the cookie lane as long as I promised her that I would come back with the cookie’s price, which she would then decide wether or not to buy it based on its price. Meanwhile she could continue with her regular grocery shopping.

On my way to the cookie lane there was a challenge though, not get lost or kidnapped. Fortunately that never happened so my promise would always get resolved and I would come back with the price :). That right there was one of the first times I got introduced to promises without even realizing it, so exciting!

Applying that in Angular is much more fun and also less dangerous, you get to make any type of request to servers that can be miles away, while you can go on with executing some other code and decide what to do when that far away server responds. All of that without even having to get away from your computer and no risks to get kidnapped, how cool is that!?

Had a lot of fun thinking how that would look like in Angular, and it would be something like:

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
28
29
30
31
32
33
34
35
36
37
38
// This is my task requested by mom every time we would go grocery shopping
function checkCookiePrice() {
  var defer = $q.defer();

  setTimeout(function () {
    // very random. I could only believe in God back then...
    var random = Math.floor(Math.random() * 3);

    if (random == 0)
      // YES!
      defer.resolve('cheap');
    else if (random == 1)
      // Well, guess I'll be eating lots of cream crackers...
      defer.resolve('expensive');
    else
      // something bad happened, oh boy..
      defer.reject();
  }, 1000); // I would definitely take longer than a second. But this is just for demonstration purposes.

  return defer.promise;
}

// This is mom's task
function doShopping() {

  checkCookiePrice()
    .then(function (kidResponse) { // first arg is a resolved promise
      if (kidResponse === 'cheap')
        $scope.momSays = "OK, we can buy it...";
      else if (kidResponse === 'expensive')
        $scope.momSays = "Are you crazy?! that's worth one kilo of rice and beans!";
      }, function () {  // second arg is a rejected promise
        // Unexpected occurrence. Fortunately this was never the case
        $scope.momSays = "Where's my kid?!?!";
    });

  // ... Mom would keep on shopping while I'd be asynchronously working on her request
}

Hopefully the comments are a bit explanatory, but here’s some more detail of what’s happening just in case:

checkCookiePrice() performs the actual task of asynchronously checking the price and returning a promise based on a few conditions. We then execute it inside doShopping() and handle the response/promise within the then(). The first argument of then() gets executed whenever the promise has been fulfilled/resolved, and the second argument is for whenenever it’s been rejected. In the meanwhile doShopping() can execute more instructions while waiting for the promise. There’s a third super cool argument that is meant for notification, but for simplicity we’ll stick with these two. There are also other ways to perform a promised based solution but in this example we’re using the $q service.

There’s much more to say about promises but hopefully that will give a better understading of what they are and what we can use them for when building a Javascript based web application.

For more useful information I highly recommend checking out this basic Egghead video on promises for a more practical example.