Promises and AJAX in ECMAScript 6

One of the major things I was using jQuery for was the interactions with my Web API. I am used to called $.getJSON() to get that data and using jQuery Deferred Objects to handle the async nature of the call. Given that with ECMAScript 6, most of the incompatibilities between browsers goes away (and thus a lot of the need for jQuery), what about AJAX?

We still have the XMLHttpRequest() object to do the request. That bit hasn’t changed. A new feature that has changed is Promises. Promises are a basic recipe that can be distilled down to “do something, then do something else, unless you fail, in which case do this other thing”. In Promise land, this turns into:

    .then(function(response) {
    .catch(function(error) {

You can cascade and interleave then/catch to catch things at different positions, but this is the basic format.

Back to my case of collecting data from my Web API. I have to code doSomething() to return a Promise and do it on an event-driven basis. If I do it right, then my code can be this:

    .catch(function(error) { throw new AJAXError(error); })
    .catch(function(error) { throw new JSONError(error); })
    .then((r) => this.doSomethingWithJSON(r); })
    .catch(function(error) { throw new ApplicationError(error); });

The basic flow is something like this. Retrieve some data from Web API, then run that data through JSON.parse() to turn it from a string into an object, then go do something with that JSON in my class. In terms of error handling, I’m going to throw a different exception for each step of the way. If I didn’t care about error handling in the individual steps, then I could do the following:

    .then((r) => this.doSomethingWithJSON(r); })
    .catch(function(error) { throw new ApplicationError(error); });

This is much simpler to read than the jQuery / ES5 equivalent code. The magic occurs because my ajaxGet method returns a Promise. At the top of my ECMAScript 6 file I’ve got the following:

import $http from "./AJAX";

This brings in my AJAX library. Here is the relevant portion of that library:

function ajaxGet(url) {
    return new Promise(function(resolve, reject) {
        let req = new XMLHttpRequest();"GET", url);
        req.onload = function() {
            if (req.status === 200) {
            } else {
                reject(new Error(req.statusText));

        req.onerror = function() {
            reject(new Error("Network error"));


export default { ajaxGet };

Notice how I return a new Promise. When a new Promise is created you pass it a function which has two arguments:

  1. What to call when you have a successful or resolved promise
  2. What to call when you have an unsuccessful or rejected promise

The contents of this function are a pretty standard XMLHttpRequest() logic where I specify two event handlers – one is the onload() which is called when the XMLHttpRequest succeeds. In here I check to ensure I get a 200 back and resolve the Promise if I do (resolving a Promise is a success criteria so it calls the next then… clause). Anything else is an error so I reject the Promise. Once that is all set up, I send the request async.

I have similar functions for ajaxPost, ajaxPut and ajaxDelete – some of them take data and some of them don’t. As long as I’m returning a Promise, I can deal with them using the Promise recipe above.