In 2005, Jesse James Garret published an essay on his company website titled Ajax: A New Approach to Web Applications, coining the term. Ajax describes a cluster of technologies used for modern web applications; technologies such as XMLHttpRequest (XHR), HTML, and JavaScript (JS), which changed the traditional approach of full-page requests to just-what-I-need requests to the server. But only the term was new, all the technologies that were mentioned had been around for a while.

 

 

Ajax

(source: http://www.websiteoptimization.com/secrets/ajax/8-1-ajax-pattern.html)

XMLHttpRequest

This API was originally designed by Microsoft for use with their Outlook 2000 Web Access, first implemented as an ActiveX object in IE5 and later as an JS object in IE7. It was not designed for the things we do nowadays, but everybody seemed to understand its possibilities, so it ended up being in all the browsers as a native JS object.

Despite its name, this API can be used to retrieve plain text and JSON too, and to use protocols like FTP. Since the update in Level 2, XHR can handle Cross-Origin XHR and process events that were added, so the creative people could imagine multiple ways to make our waiting more pleasant.

Even with the additions, XHR was not designed for what is used, and due to this, it has some limitations. The developers might have become familiar with its semantics, but that does not mean it is clear. You have to create an object, then call their methods. But, they are asynchronous, so you cannot pass the result directly to your function, you have to use callbacks. When they pass the data, it ends up working, but it is a little confusing. Here’s an example:

 

function listener() {  
  var data = JSON.parse(this.responseText);  
  console.log(data);  
}

function error(err) {  
  console.log('Request error', err);  
}

var oReq = new XMLHttpRequest();  
oReq.onload = listener;  
oReq.onerror = error;  
oReq.open('get', './api/some.json', true);  
oReq.send();

It is about time to simplify this. Of course, there are a lot of attempts to do this, like the ajax function of jQuery and other libraries and frameworks. But, something new is coming, it’s called Fetch: the new Ajax.

The Fetch API

With Fetch, you can make a request just like with XHR. The main difference is that Fetch uses Promises. Here’s some code that explains the difference:

 

fetch('./api/some.json')  
  .then(  
    function(response) {  
      if (response.status !== 200) {  
        console.log('There was a problem. Status Code: ' + 
          response.status);  
        return;  
      }

      // Examine the text in the response  
      response.json().then(function(data) {  
        console.log(data);  
      });  
    }  
  )  
  .catch(function(err) {  
    console.log('Fetch Error', err);  
  });

As you can see, the semantics in this code is clearer, and the operation returns a value, like a synchronous operation. Compare this to the XHR example: they both do the same, but the one that looks simpler is Fetch. The code is clear. You do the request, then handle the response. Each Promise can be chained to the next one, so they can share logic between requests.

Let’s take a step back and talk about Promises. A Promise represents the result of an asynchronous operation and it can be in one of three states: pending, rejected or fulfilled. When a promise is not pending, it means that is settled. That could mean that it has now a value (fulfilled) or a reason (rejected), so an asynchronous operation can return a promise as a synchronous one can return a value.

 

Promises workflow representation

(source: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)

Now that we have explained Promises, let’s look deeper into Fetch. With Fetch, we can access metadata really easily. We can get information like this from the response object:

response.headers.get('Date');
response.headers.get('Content-Type')

Or simply get them all:

response.headers.getAll();

In the response, we can get additional information, such as the response type. The values can be: cors, to indicate a cross-origin request; basic, the same origin request; or opaque, a cross-origin request that does not return the CORs headers.

As I explained before, Promises can be chained. Let’s see an example of how this is applied to Fetch:

function status(response) {  
  if (response.status >= 200 && response.status < 300) {  
    return Promise.resolve(response)  
  } else {  
    return Promise.reject(new Error(response.statusText))  
  }  
}

function json(response) {  
  return response.json()  
}

fetch('users.json')  
  .then(status)  
  .then(json)  
  .then(function(data) {  
    console.log('Request succeeded with JSON response', data);  
  }).catch(function(error) {  
    console.log('Request failed', error);  
  });

In conclusion Fetch simplifies the maintaining, debugging and testing of the code, and will be a standard soon in all browsers. You can try it now in Chrome 42+ and Firefox (Gecko) 39+. For more information, go to the Firefox Developer Web Page.

 

You must be logged in to post a comment.
Menu