We mainly took a look at completely new features that come with the Angular 1.3 release until now. Things like ngModelOptions, Angular-hint or One-time Bindings are not just minor improvements, but rather real extensions to the framework. However, there have not only been significant new features added to the release, but also a ton of bug fixes and nice little additions that we might have overlooked. One of them is the ES6 streamlined promise API and today we gonna take a look what it brings to the table.
TABLE OF CONTENTS
Asynchronous worlds with Promises
In order to understand what the new streamlined addition to the existing promise API means, we first have to make sure we’re all on the same page and know what promises are and how they’ve been implemented in Angular before. We don’t want to go in too much detail here though, since there are a ton of resources in the interwebs, but let’s take a very quick look at promises and move on then.
Here’s an example:
Here we have a function
onceDone() that expects a function that is executed, once the
onceDone() function is done with its work and it doesn’t block the rest of the code that might be there.
You get the idea right? While it is very common to have function calls that get a function callback, it can lead to very hard to get right code when we have to nest a lot of these. I recommend to head over to callbackhell.com to get a better picture, if things are still unclear.
Promises are a software abstraction or proxies, that make working with asynchronous operations much more pleasant. Coming back to our
onceDone() function example, here’s what the code would look like if
onceDone() used promises.
Looks very similar right? But there’s a huge difference. As you can see,
onceDone() returns something that is a promise which we can treat as first-class objects. This promise holds the actual state of the asynchronous code that has been called, which can be
pending. We can pass promises around and even aggregating them. That’s a whole different way of handling our asynchronous code.
What we also see, is that the promise has a method
.then(). This method expects two parameters which are functions of which one gets called when the asynchronous execution was fulfilled and the other one when it was rejected.
As I mentioned, we can aggregate them.
.then() also returns a promise that resolves with the return value of the executed handler (
rejected). That enables us to chain promises like this:
Compare this with our callback hell code snippet and you know why promises are so powerful. In fact, there’s a lot more about promises to tell, but that’s out of the scope of this article. If you want to read more about promises in general, I recommend reading Domenic’s article and the MDN docs on promises. But let’s get back to promises in Angular.
Promises in Angular and
Angular comes with a promise implementation by default. It has a $q service that we can of course inject and use though-out our application. Angular’s implementation is highly inspired by Kris Kowal’s Q library which is an implementation of the Promises/A spec.
It comes with a
Deferred API which lets you get instances of deferred objects that hold a promise object. We can use the API of a deferred to either resolve or reject a promise depending on what our code should do. Here’s a quick example:
We have a function
anAsyncFunction() which is asynchronous and we use the deferred API to get a promise out of it. One thing to notice here is that our function doesn’t know anything about promises but we use the deferred API to get a promise back. The deferred API comes with a few more features that I don’t want to detail here, but you can read about them in the official docs.
Have you ever used Angular’s
$http service? Sure you did. And as we know, XMLHttpRequests are asynchronous too. Guess what
$http service uses to expose its
.error() APIs? Right. Promises. When making XHR calls with
$http we’re also using
$q implicitly. It just adds some sugar APIs to the promise it returns:
In fact, we can use the promise native APIs to achieve the same:
Okay, so we now got a picture of promises in Angular. There’s also a nice talk by the awesome Dave on promises at ngEurope, I recommend checking that one out too. But what is it with the ES6 style promises that we’ve mentioned in the blog title?
ES6 style Promises in Angular 1.3
Although it’s nice to have the deferred API in Angular to deal with promises, it turns out that the ECMAScript standard defines a slight different API. Taking a look at the MDN docs on Promises, we see that
Promise is a constructor in ES6 that takes an
executor function that has access to a
resolve and a
reject function to resolve and reject promises respectively.
Angular 1.3 streamlined its promise APIs partly with the ES6 standard. I say partly here, because not all methods are supported yet. However, what the team has streamlined is that
$q can also be used as a constructor now.
So instead of doing creating a deferred like this:
We can now use the promise constructor API and return it directly without creating a deferred object first:
Even if this is just an optical difference at a first glance, it’s nice to know that we can safe the lines of code to create a deferred first. Also, the fact that the
$q API is now closer to the actual spec makes the code more reusable in the future.
Now we might wonder, if we have to change all of our code where we’ve used
$q.defer() to work with promises. The answer is no. As mentioned at the beginning of the article, this is a nice small addition (rather than a new feature or replacement) in the 1.3 release that doesn’t break the code.
Get updates on new articles and trainings.
Join over 1400 other developers who get our content first.
Futuristic Routing in Angular
An this article we discuss the new router APIs and how it's going to change the way we implement component...
ngMessages in Angular 1.3
In this article we're going to how the ngMessages module improves the way we handle validation messages when dealing with...
Go fast with $applyAsync in Angular 1.3
Angular 1.3 comes with a feature to share a running $digest cycle across multiple XHR calls. This articles details how...
Validators Pipeline in Angular 1.3
In this article we discuss a newly introduced feature called custom validators, so we don't have to hijack parsers and...
Binding to Directive Controllers in Angular 1.3
In this article we are going to take a look how to bind values to directive controllers to make them...
Disabling Debug Info in Angular 1.3
This article details how to give your app a performance boost in production environments with just a single line of...
You might also be interested in
Exploring Angular 1.3: One-time bindingsRead more
Exploring Angular 1.3: ng-model-optionsRead more
Exploring Angular 1.3: Angular-hintRead more
Exploring Angular 1.3: Stateful FiltersRead more
Exploring Angular 1.3: Disabling Debug InfoRead more
Exploring Angular 1.3: Binding to Directive ControllersRead more
Exploring Angular 1.3: Validators PipelineRead more
Exploring Angular 1.3: Go fast with $applyAsyncRead more
Exploring Angular 1.3: ngMessagesRead more