AngularJS Javascript

Clean code chaining $q promises

$q promises for angular are not only good for async tasks but an incredible way to write clean and readable code.

Since a few months, I’ve decided to write my code in very small functions with its in/out parameters and its detailed documentation.

Maybe you are not following the relation between $q promises and organizing the code in small-low-complex functions. I’m explaining myself.

Once you understand the way promises work (Ben Nadel wrote an incredible article about them) you can use promise chaining to execute different steps of your code, capture errors and avoid a pyramid of doom.

Let me show you how. Code below represents a method that activates a user, following next steps:

  1. Check params
  2. Obtains the user
  3. Enables the user
  4. Obtains a login token for the valid user

I’m not going to explain what is this code for, but resuming it, it performs some requests to an API, apply some filters, controls different error codes and finally assigns data to $scope to be painted in the interface.

What draws attention in the code above is:

  • The pyramid of doom: I’m used to limit my lines to 80 characters and maybe that’s why I like to control this. It might sound crazy to have 80 chars limit, but I will discuss this in a future article.
  • This code is unreadable at a glance: It is well documented but quite difficult to follow.
  • The impossibility to follow errors and their codes: They are created at different places.

Here is where promise chaining is going to make a difference.

Let’s see code below, the result of its execution is the same but more readable and organized. I’ve split previous activate function into different small functions: getUser, enableUser and getUserToken. Each small function is doing its work, resolving data or rejecting its error codes. These functions are chained and executed inside the method activate.

As you can see, code is more readable and clean, each small function might be well documented. You can use callbacks too but I love the way I can control successful/error flows just chaining then and catch ?.