A FULFILLED PROMISE - Using the FETCH API to make AJAX calls

Making partial web page updates by using fulfilled promises with fetch

by Iveta Karailievova Date: 26-12-2020 JavaScript fetch promise AJAX

In this article we talked about what AJAX calls are and how to use them in a traditional way, by using the XMLHttpRequest (XHR) object. In short, thanks to AJAX calls a web page can be partially updated without having to reload the whole content. This leads to better loading speeds, usability and nowadays is an indispensable part of modern web development. Now we will focus on a more modern approach, which is by using the fetch Web API. 

In this article, as an example, we will build a functionality which generates and diplays on our page random Rick and Morty characters. The only language we need to use is plain (vanilla) JavaScript, and the rest of the magic (the back end part) will be provided by the Rick and Morty REST API

Web APIs - what are they?

A Web API is an application programming interface for the Web. To put it simply, when you write code for a web page, you may use a web API, which makes your job way easier, for example, by providing the web browser with more the functionality, by simplifying complex functions or by simplifying the code’s syntax. One of those useful APIs is fetch, which helps us to make web requests in a more intuitive and simpler way.

What is the fetch API and why is it better than XHR?

It is a relatively new, native JavaScript API. Fetch API was introduced with ECMAScript 6, also known as ES6 and ECMAScript 2015, which was the second major revision to JavaScript. 

Fetch allows you to make asynchronous network requests to web servers similar to the XMLHttpRequest, but with the advantage of being more elegant, simpler and cleaner. The main difference between XHR and FECTH API is that the Fetch API uses Promises. Thanks to this, you will not have to deal with callback functions and the callback hell they could potentially result in. Also, with XMLHttpRequest, the syntax you need to use in  your code is more complex and thus might lead to errors. We can without doubt say that fetch API is an improvement over the traditional XMLHttpRequest method, and it offers us more features.

Although it is supported by most browsers today, it is not supported by Internet Explorer. So if you need your code to be compatible with IE, you should consider using polyfills. These are basically pieces of JavaScript code responsible for providing modern functionality on older browsers that do not natively support it.

How to use fetch – an example where we retrieve data from an API

As its name suggests, the fetch API provides an interface for fetching, obtaining resources. In order to call the fetch method, we need to supply one argument – the URL or path to the resource from which we want to get our response. 

Let’s get practical and start setting up our example. Here is the HTML markup:

in our index.html file, we put inside the <body> element:

<main>
<label for="number">Choose a number</label><br>
<input id="number" type="number" min="1" max="671" />
<figure>
<img id="avatar" src="" alt="" />
</figure>
</main>

and to make it a little more appealing, some CSS:

body {
background-color: coral;
color: grey;
font-size: xx-large;
text-transform: uppercase;
text-align: center;
font-family: Verdana, Geneva, Tahoma, sans-serif;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}

Next part - our vanilla JavaScript code with the fetch method

Let’s start with the easy part – creating constants to access the DOM elements which we are going to need:

// the inputValue allows us to access the value of the user's input, i.e. the chosen number
const inputValue = document.getElementById('number')
// this constant allows us to set the image to be displayed, by dynamically changing its "src" attribute
const avatar = document.getElementById('avatar') 

Since we want to be able to access different characters, so we keep the id part flexible – by using the replace() method. We will be supplying the "id" number dynamically, when the user changes the value of the input form.

const API_URL = 'https://rickandmortyapi.com/api/character/:id'
const URL = API_URL.replace(':id', id)
fetch(URL)

And now the interesting part – the fetch method returns a promise.

What is a JavaScript promise? 


Promises are a modern approach, a solution to the problems callback functions brought upon us. A promise is a placeholder for a value it will hold in the future, when the asynchronous request is resolved. To this promise, we can attach handlers, so that certain action is carried out in the case the promise is fulfilled and another if the promise is rejected. 

You could also think of a promise being in some ways similar to an event, but with the difference that a promise can only succeed or fail once, and that the result is final, meaning it cannot switch from being fulfilled to being rejected or vice-versa. 

In our case, the promise will at some point in the future contain the response, more precisely a Response object, a HTTP response. But careful – in order to be able to work with the actual data we received from the API, we first need to extract the response’s body, by using the json() method. This way, we parse the response into JSON. But, and this might seem somewhat confusing, the json() method returns another promise. This is because the reading of the stream containing the response is happening asynchronously.

We work with promises by assigning handlers to them, namely the then() and catch() method.

Promises can have one of the following states:

  • pending – this state is assigned automatically after the promise is created, it means so far the promise was neither fulfilled nor rejected;

  • fulfilled – the promise has been completed with success and the result we obtain is the value of the operation;

  • rejected – the promise has not been completed successfully, and the result we obtain is the reason why this happened (the error);

Handling errors when using fetch

in the case of fetch method, the fetch promises are rejected only when a network error is encountered (such as permissions issues, misconfigured CORS on the server-side, DNS lookup failure, etc.) HTTP responses with codes 4xx and 5xx are not network errors, so the catch() attached to the promise will not be fired in the case of these types of errors. That is why we need to check the fetch response’s ok property, like this:

if(response.ok)

it returns a Boolean value, being true if the response returned successfully.

By adding the following error-handling function, we can make sure that our errors are thrown and catched correctly, like in the case that the user chooses an id which is out of the APIs range of characters:

function handleErrors (response) {  
    if (response.ok) {
       return response
}
     throw new Error(response.statusText) 
}   

So, now we have to chain all the promise then() methods, like this:

function getCharacter (id) {
  const URL = API_URL.replace(':id', id)
  fetch(URL)
  // first we attach the error handler function
    .then(handleErrors)

// next, if there was no error, we use the json method on our response object
    .then(function (response) {
      console.log(response)
      return response.json()
    })

    // since the response.json() method used on a Response object returns another promise, we attach another then handler on the data we receive

    .then(function (data) {
      const newCharacterJSON = data
      // upon studying the response data structure, we know we need to access the "image" JSON key to get the image URL
      var imagePath = newCharacterJSON.image

      // now we set the src attribute of our image element to the URL from the reponse
      avatar.setAttribute('src', imagePath)
    })
    // this part of the code allows us to correctly catch the errors which might have appeared, both errors of the original promise being rejected as well as the errors which are thrown by our handleErrors function
    .catch(function (err) {
      console.log('Something went wrong!', err)
    })
}

Note: the response you get is not JSON, but an object with a series of methods that can be used depending on what you want to do with the information. Since the Rick and Morty API we’re using will return JSON to us, the returned response will have .json() method. We just need to call .json() on the response variable.

And finally, we need to think of a way of calling the function. We do this by adding an event listener to our input element. In this example we chose to use the change event, which gets triggered every time the value of the input field gets changed.

inputValue.addEventListener('change', function () {
const choosenNumber = inputValue.value
getCharacter(choosenNumber)
})

To take a better look on this solution, here you can see the full code and a working demonstration.

Conclusion

Even though the results we are getting might seem the same, using fetch API over XMLHttpRequest seems to be the correct way to write our code in the future, because it allows us to handle responses in a more organized way and spares us the trouble of descending into our little callback hell.

 
by Iveta Karailievova Date: 26-12-2020 JavaScript fetch promise AJAX hits : 9376  
 
Iveta Karailievova

Iveta Karailievova

Originally coming from a marketing background, decided to turn her life around and immerse herself into the wonderful exciting and most importantly – never boring world of technology and web development. Proud employee at MA-NO . Easily loses track of time when enjoying working on code. Big fan of Placebo, cats and pizza.

 
 
 

Related Posts

How to upload files to the server using JavaScript

In this tutorial we are going to see how you can upload files to a server using Node.js using JavaScript, which is very common. For example, you might want to…

How to combine multiple objects in JavaScript

In JavaScript you can merge multiple objects in a variety of ways. The most commonly used methods are the spread operator ... and the Object.assign() function.   How to copy objects with…

The Payment Request API: Revolutionizing Online Payments (Part 2)

In the first part of this series, we explored the fundamentals of the Payment Request API and how it simplifies the payment experience. Now, let's delve deeper into advanced features…

The Payment Request API: Revolutionizing Online Payments (Part 1)

The Payment Request API has emerged as the new standard for online payments, transforming the way transactions are conducted on the internet. In this two-part series, we will delve into…

Let's create a Color Picker from scratch with HTML5 Canvas, Javascript and CSS3

HTML5 Canvas is a technology that allows developers to generate real-time graphics and animations using JavaScript. It provides a blank canvas on which graphical elements, such as lines, shapes, images…

How do you stop JavaScript execution for a while: sleep()

A sleep()function is a function that allows you to stop the execution of code for a certain amount of time. Using a function similar to this can be interesting for…

Mastering array sorting in JavaScript: a guide to the sort() function

In this article, I will explain the usage and potential of the sort() function in JavaScript.   What does the sort() function do?   The sort() function allows you to sort the elements of…

Infinite scrolling with native JavaScript using the Fetch API

I have long wanted to talk about how infinite scroll functionality can be implemented in a list of items that might be on any Web page. Infinite scroll is a technique…

Sorting elements with SortableJS and storing them in localStorage

SortableJS is a JavaScript extension that you will be able to use in your developments to offer your users the possibility to drag and drop elements in order to change…

What is a JWT token and how does it work?

JWT tokens are a standard used to create application access tokens, enabling user authentication in web applications. Specifically, it follows the RFC 7519 standard. What is a JWT token A JWT token…

Template Literals in JavaScript

Template literals, also known as template literals, appeared in JavaScript in its ES6 version, providing a new method of declaring strings using inverted quotes, offering several new and improved possibilities. About…

How to use the endsWith method in JavaScript

In this short tutorial, we are going to see what the endsWith method, introduced in JavaScript ES6, is and how it is used with strings in JavaScript. The endsWith method is…

Clicky