Using promises is tricky at first. Every newcomer to Angular will be flustered about them. It’s super easy to get lost at first between all the different nitpicks: promise chaining,
$http’s special promises, the asynchronous nature of it all, etc.
One of the first questions you tackle starting to learn promises is when, if at all, should you use
$q.defer() quite often when I first started with Angular. You know how much of that original code actually needed to use
defer()? About none at all.
I realized that there was almost no reason to use
defer() to create my own promises. It’s just cumbersome and error prone.
And guess what? I think that nearly everyone that uses it does it unnecessarily.
Real examples from GitHub
First, a disclaimer: this isn’t some sort of shaming. I used to write lots of code just like this. I want to show how common this problem is with real code and no handwaving.
I opened GitHub’s code search and started looking for people using
$q.defer(). In the first 3 pages of results I saw about 2 actual valid use cases. Yeeeep.
You don’t need defer to create a simple-valued promise
Let’s take a look at this case:
1 2 3 4
It’s easy to see the author just wanted to create a promise with some hard-coded value. Those 4 lines? They can just be rewritten as:
You don’t need defer to change the value of a promise
1 2 3 4 5
This successfully creates a promise that you can call with
.then() and receive as a value the actual response body. But, through the magic of promise chaining you can simplify this:
1 2 3
Promise chaining is a bit complicated, but the gist is this: inside a promise’s
.then() whatever you
return will be passed along to the next
.then() along the chain.
This means that in our example above we’re returning a regular promise whose
.then() will pass
response.data – sweet!
Sometimes you don’t need to do anything at all
Just about anything asynchronous is already a promise in Angular. Take a look at this:
1 2 3 4 5
The author wanted to return a promise that would get resolved once 5 seconds have passed. But guess what?
$timeout already returns a promise that does just that, allowing us to write this:
When should you use defer?
Basically, the main reason is:
You’re converting a callback API to be promise-based: For example, if you wrap a jQuery plugin to work in Angular. Callbacks are not as fun as promises. To kickstart the promise chain and convert callbacks you have the create the first promise.
I’ve written about actually creating promises here.
Do you have an existing Angular 1.x app that makes you worried about its future?
You don’t want your app to be left behind and become legacy code.
But it’s not easy clearing the time to learn Angular 2.
And who has the energy to convince management that you need to change frameworks, delay your schedules and do the Big Ol’ Rewrite?
But what if you could make sure your app keeps its options open?
What if you could make it future-proof, all the while shipping features like a boss?
You’ll work in a codebase that uses the latest and greatest, have easy maintenance and happy stakeholders!
The Future-proof Angular Guide can help you get there.
With this no-fluff course you’ll learn how to quickly adapt your existing Angular 1.x app to the latest components paradigm, as you go about your regular work.
You’ll gradually turn your app into something that is modern and idiomatic, converting directives and getting rid of controllers.
And then, once your app is shaped The Right Way™, you’ll be able to keep shipping like a boss, and have your options open.
Sign up to be notified when the course is ready (and get more of these pragmatic Angular posts in the meantime).