Making AJAX requests to a REST API using vanilla JavaScript and XHR

Learning AJAX with Rick and Morty REST API

by Iveta Karailievova Date: 25-11-2020 AJAX API REST API vanilla JS JS XHR

Imagine you just build your first static web page and you would like to add some functionality to make it more attractive and generally more usable. Perhaps you would like to entertain your web page visitor with randomly generated cat facts, jokes, or, (preferably not randomly generated) weather forecasts or stock exchange information. How to achieve this? With AJAX calls! These come in handy in situations where you need to obtain data from another server. Thanks to AJAX, you can dot your web page with interesting content supplied by a third-party server, using only front-end development knowledge. In this article, as an example, we will build a functionality which generates and diplays on our page random Rick and Morty characters (I’m sure most of you nerd know the series pretty well but for those who don’t, I highly recommend it). 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

REST API ENDPOINTS

You can simply think of them as URLs, where when you sent a correctly formulated HTTP request, you obtain a response, almost always in JSON or XML format. To communicate with a REST API you need to use HTTP and specify the method: GET, POST, PUT,PATCH or DELETE. In our case, we will only use the GET method, because we want to GET and read the data (an image) from the server.

But what does AJAX have to do with all this?

The name might remind you of a football club or a cleaning agent, but the AJAX we are going to talk about today is something else. AJAX, as we already said, is a technique that allows you to add interactivity to your web page and make it more dynamic by communicating with a web server. Content on your web page can be updated upon mouse click or any other DOM event. Most importantly – thanks to this method the changes are carried out without needing to refresh or reload the page! This leads to a better and more fluid user experience.

This technique’s name hides the secrets to its magic:

  • Asynchronous: this is a really important characteristic because thanks to the code being executed in an asynchronous manner, our web can be displayed without any delays. Imagine you want to add an interesting feature to your web like up-to-date weather forecast, and you do so by querying a foreign server with weather information API. Now, if the server where the forecasting service runs happens to have an outage, your page, if it wasn’t for asynchronicity, would also break, because other parts of your code could not be executed because the program would be stuck waiting for the faulty weather server to send its response (which might not happen ever). Thanks to the AJAX calls being asynchronous, code responsible for requesting and receiving the response from a different web server is carried out in the background, not causing any delays in displaying other parts of the page. So, while the part of the code where a response is awaited may be waiting, other parts continue and only after the results from the API arrive, the content is updated accordingly. 
  • JavaScript: the scripting language used in the front end part to make these calls work. It is also responsible for manipulating the DOM elements to display the data we received in the server’s response.
  • XML: this part is somewhat misleading. Historically, only data in XML format was send as response. Nowadays, the response we get from the server may be in different formats, not only XML, but also JSON, HTML or plain text.

All this theory is piling up on us, but the real life usage is really super-simple. Let’s get back to that promised Rick and Morty example.


Getting started – setting up the AJAX example HTML and CSS code

So, this is our setup:

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="" />
<figcaption id="imageDescription"></figcaption>
</figure>
</main>

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

body {
background-color: pink;
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;
}

And now the most important part - our vanilla JavaScript code

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')
// here we create a link to the image description element, so we can change the displayed character name
const imageDescription = document.getElementById('imageDescription')
 

So how exactly does AJAX do its magic? Currently there are two main ways in which we can setup a working AJAX call, using XHR or the more modern FETCH API. In this article, we will use the traditional, XHR Object way.

XHR (XMLHttpRequest Object)

The XHR Object stands for XMLHttpRequest. It is a special object already built-in in every modern web browser. This object is what allows us to make requests to a web server and to obtain the responses it sends back. 

In JS, this object is instantiated like this:

var request = new XMLHttpRequest()

note: we used the variable name “request” in this example but developers often also name it “xhttp”

The next step is to use the XHR object’s open method to create a connection with the remote server. This is done by setting the HTTP method and the server’s URL. For the sake of keeping this example nice and easy, we are going to only cover the GET method. This HTTP method is used when you want to obtain data from a server, and it also allows you to pass some parameters in the form of URL parameters. In our example, we want to GET the image of a character. To do this, we need to let the remote server know, which character’s image we want to display. So, we sent the character’s ID in the URL. To make it possible for us to easily modify the ID of the character we want to obtain, we use a constant with a regEx:

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

Next we set the request headers, to indicate the web server that we are using XHR as our request technique. Many JS libraries, like Prototype or JQuery add this header automatically. It indicates that the request was made by XMLHttpRequest instead of being performed by clicking a hyperlink or by submitting a form. But why do we need to tell the web server we are using AJAX? The answer is security -  in this way, we are letting the web server know that the request has not been tampered by a hacker.

request.setRequestHeader('X-Requested-With', 'XMLHttpRequest')

Since we know that the data we receive from our Rick and Morty API will be in JSON format, we need to let our request Object aware of that:

request.responseType = 'json'

The next part is really interesting: we use the load event, which is fired when an XMLHttpRequest transaction completes successfully. This event is supported by most modern browsers and can be used as a replacement for the traditional onreadystatechange event. To handle it, we need to use the property onload. Also, a callback function, which does the actual work is needed.

The basic syntax is the following:

XMLHttpRequest.onload = callback

In our example, it looks like this:

request.onload = function () {
    // the response status tells us the HTTP status code, if it is 200, it means the response status is "OK"
    if (this.status === 200) {
      // we save the response into a variable
      var newCharacterJSON = this.response
      console.log(newCharacterJSON)

      // 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)

      // to get the image description, we access the "name" JSON key
      var characterName = newCharacterJSON.name
      if (characterName) {
      // we set the text to show the name we got from the response
        imageDescription.innerHTML = characterName
      } else {
        // if no input has been given, we display the message to choose one
        imageDescription.innerHTML = 'Please choose a number'
      }
    } else {
      // if the response status is different from 200, an error ocurred (the ID may be out of range)
      imageDescription.innerHTML =
        `An error occurred during your request! Choose a different number. Code: ${request.status}`
    }
  }

And the final piece of code, we use the send method:

request.send()

After wrapping those steps in a function which accepts the character ID number as parameter. We now have the following:

function getCharacter (id) {
  const URL = API_URL.replace(':id', id)
  request.open('GET', URL)
  request.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
  request.responseType = 'json'
  request.onload = function () {
    // the response status tells us the HTTP status code, if it is 200, it means the response status is "OK"
    if (this.status === 200) {
      // we save the response into a variable
      var newCharacterJSON = this.response
      console.log(newCharacterJSON)

      // 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)

      // to get the image description, we access the "name" JSON key
      var characterName = newCharacterJSON.name
      if (characterName) {
      // we set the text to show the name we got from the response
        imageDescription.innerHTML = characterName
      } else {
        // if no input has been given, we display the message to choose one
        imageDescription.innerHTML = 'Please choose a number'
      }
    } else {
      // if the response status is different from 200, an error ocurred (the ID may be out of range)
      imageDescription.innerHTML =
        `An error occurred during your request! Choose a different number. Code: ${request.status}`
    }
  }
  request.send()
}

But wait, how do we call the function? Easily, we just need to add an event listener to our input element. In this example we chose to use the changeevent, which gets triggered every time the value of the input field gets changed.

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

So, if you made it this far, well done! You can have a look here to see the full code and a working demonstration of this exercise.

 
by Iveta Karailievova Date: 25-11-2020 AJAX API REST API vanilla JS JS XHR hits : 16446  
 
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

Why businesses need to be familiar with APIs

APIs serve as intermediaries between software, allowing them to communicate with each other and perform various functions like data sharing or processing. APIs provide the protocols, definitions, tools, and other…

How to Track Flight Status in real-time using the Flight Tracker API

The Flight Tracker API provides developers with the ability to access real-time flight status, which is extremely useful for integrating historical tracking or live queries of air traffic into your…

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…

How to connect to MySQL with Node.js

Let's see how you can connect to a MySQL database using Node.js, the popular JavaScript runtime environment. Before we start, it is important to note that you must have Node.js installed…

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

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…

Why You Should Hire Node.js Developer for Your Backend Development

When developers are building a new website, they mainly focus on both frontend and backend development. The frontend code helps create the interfaces through which the app interacts with the…

Data Scraping and Data Crawling, what are they for?

Right now we are in an era where big data has become very important. At this very moment, data is being collected from millions of individual users and companies. In…

How to Install Node.js and NPM on Ubuntu 18.04

Node.js is a JavaScript platform for general programming that allows users to create network applications quickly. By leveraging JavaScript in both frontend and backend, Node.js makes development more uniform and integrated.…

Easy Face and hand tracking browser detection with TensorFlow.js AI and MediaPipe

In March the TensorFlow team has released two new packages: facemesh and handpose for tracking key landmarks on faces and hands respectively. This release has been a collaborative effort between…

How to Generate Static Sites with JavaScript Static Sites Generators

Static websites and so-called JAMstack have become pretty popular recently. And with 2020 on the horizon, this trend doesn't seem to be stopping. Why? Why is old-school HTML + CSS…

CRUD Operations Using Vue.js: a basic example

In this tutorial, we show you how to create CRUD application using vue js. here is very basic and simple example of vue.js crud app. using this vuejs crud (create read…

Clicky