Fetch API Guide. Javascript Asynchronous request in 2017.

I still see many questions about AJAX, asynchronous callbacks and closures inside them on stackoverflow.

  • @skip bulshit
  • @example of usage

But now Fetch API appears on scene!

What is Fetch API

It's a high level API already implemented in all browsers (that real users, not bots, use):
IE Edge, Google Chrome, Mozilla Firefox, Android Browser & Chrome for Android, Safari and even iOS Safari (since 10.3 version).

For older browsers (we all like bots) there is wonderful worry-free polyfill https://github.com/github/fetch

Fetch Api should replace old mammoth XHR (XMLHttpRequest) in our minds.

Instead of:

var xhr = new XMLHttpRequest();  
xhr.onreadystatechange = function() {  
    if (xhr.readyState == XMLHttpRequest.DONE) {
        alert(xhr.responseText);
    }
}
xhr.open('GET', 'http://test.huncode.com/get', true);  
xhr.send(null);  

We have awesome:

fetch('http://test.huncode.com/get')  
.then(function(response) {
  alert(response.text());
});
So, fetch API is a new XHR, that's next?

In most of cases we use asynchronous requests to get JSON from our application API and to send forms. Let's consider this cases.

If you need an endpoint to test your application, you can use test.huncode.com:

GET, response 200: https://test.huncode.com/get
GET, response 401: https://test.huncode.com/get/401
GET, response 500: https://test.huncode.com/get/500

POST, response 200: https://test.huncode.com/post
POST, response 400: https://test.huncode.com/post/400
POST, response 500: https://test.huncode.com/post/500

Fetch API examples.

Case #1. Get request to JSON API. API located on the same domain.

fetch('http://test.huncode.com/get')  
.then(response => {
  // Check HTTP response status is 2XX
  if (response.ok) {
    return response;
  }
  // Else raise a reject to catch in our .catch function
  throw Error(response.statusText);
})
.then(response => response.json())
.then(json => {
  // our json is here
})
.catch((error) => {
  // Error in response happened
  // Check HTTP response body with error message
  console.log('ERROR!' + error.message);
});

Case #2. Get request to JSON API. API located on different domain, so we need CORS.

BOOM! CORS is enabled by default, you can just take previous example.
But you are awesome web developer and like to keep all the things under control.

fetch('http://test.huncode.com/get', {  
  mode: 'cors',
  credentials: 'include' // send cookies with the request
})
.then(response => {
  // Check HTTP response status is 2XX
  if (response.ok) {
    return response;
  }
  // Else raise a reject to catch in our .catch function
  throw Error(response.statusText);
})
.then(response => response.json())
.then(json => {
  // our json is here
})
.catch((error) => {
  // Error in response happened
  // Check HTTP response body with error message
  console.log('ERROR!' + error.message);
});

Case #3. POST form to backend.

const data = { username: 'user', password: 'password' };  
fetch('http://test.huncode.com/post', {  
  method: 'post',
  headers: {
    'Content-Type': 'application/json' // tell the server to process sent text as JSON
  },
  body: JSON.stringify(data) // send JSON as string
})
.then(response => {
  // Check HTTP response status is 2XX
  if (response.ok) {
    return response;
  }
  // Else raise a reject to catch in our .catch function
  throw Error(response.statusText);
})
.then(response => {
 // Process response:
 // if it's a JSON: response.json()
 // if it's a text or html: response.text()
 // and do smth with response
})
.catch((error) => {
  // Error in response happened
  // Check HTTP response body with error message
  console.log('ERROR!' + error.message);
});

Next step will be getting blob objects (like images) and post a true form with content type 'application/x-www-form-urlencoded'

If you are not satisfied of this article, keep reading specification: https://fetch.spec.whatwg.org/#fetch-api