In this article, we’ll be looking at how we can go about retrieving data from a server. Modern websites and applications need to be able to do this seamlessly — that is, update sections of a web page without needing to reload the entire page. We’ll be looking at two technologies that make this possible: XMLHttpRequest and the Fetch API.

This article continues on from my previous: Understanding APIs. If you’re new to working with APIs, be sure to check it out first!

The old way...

Page loading on the web using old methods was quite simple — you would send a request for a website to a server, and if nothing went wrong, any assets that made up the page would be downloaded and displayed on your computer or device.

This was the way websites worked for years. However it had a number of flaws.. whenever you wanted to update any part of the page, for example, to display a new set of products or submit a form, the entire page had to load again. This practice is very resource-heavy and results in a poor UX, especially as pages grow and become more complex.

The solution: AJAX

This problem was resolved as technologies were created that allowed web pages to request small chunks of data (such as HTML, XML, JSON, or plain text) and display them only when needed.

This is achieved by using APIs like XMLHttpRequest or the Fetch API. These technologies allow web pages to directly handle making HTTP requests for specific resources available on a server and formatting the resulting data as needed before it is displayed.

This technique is what is called “Ajax”, or Asynchronous JavaScript and XML. Originally it mainly used XMLHttpRequest to request XML data (hence the “and XML”). However, these days you'd be more likely to use XMLHttpRequest or Fetch to request JSON — but the result is still the same so the term "Ajax" stuck.

Conceptually, Ajax involves using a web API as a proxy to more intelligently request data, rather than just having the browser reload the entire page.

You can see it in action in just about every major website. When you play a new video on YouTube for example, you’ll see the navigation, header and footer sections don’t refresh — just the section containing the video.

Why is this important?

  • Page updates are much faster & you’ll spend less time wait for the page to refresh, so the site feels faster and more responsive (page speed is also very important for Google rankings and SEO!).
  • Less data is downloaded on each update, meaning less wasted bandwidth. Whilst not a huge concern on desktops, it’s a major issue on mobile devices especially in developing countries that don’t have fast Internet.

Creating an Ajax request

In this section, we’re going to first use an XMLHttpRequest and then Fetch to perform an Ajax request.

XMLHttpRequest

An XMLHttpRequest (often abbreviated to XHR) is actually quite an old technology now — it was invented in the ‘90s by Microsoft, and has been in use ever since.

To create an XHR request, you first need to create a new request object using the XMLHttpRequest() constructor. You can call this object anything you like, in our demo we’ll call it xhr. Like so:

let xhr = new XMLHttpRequest(); 

The next step is to initialize it using the open() method. Here we specify what HTTP request method to use to request the resource from the network, as well as the URL where it’s located. Here we’ll use the GETmethod and set the URL to a url variable (which should store the address as a string).

We add this below the previous line:

xhr.open('GET', url);

Next, we’ll set up the type of response we are expecting as text. This isn't strictly necessary as XHR returns text by default — but it is a good idea to get into this habit as you’ll no doubt be fetching other types of data in the future! Now we add:

xhr.responseType = 'text';

Whenever we fetch a resource from a network we’re performing an asynchronous operation. This means you have to wait for that operation to complete (while the resource is returned from the network) before you can do anything with that response, otherwise, an error will be thrown. With XHR we can handle this using the onload event handler — this runs when the load event fires (after the response has returned). The response data will be available in the response property of the XHR request object.

Next, we create our function to handle the onload event & (in this case ) display our xhr.statusxhr.response values:

xhr.onload = function() {
  alert(`Loaded: ${xhr.status} ${xhr.response}`);
};

And finally, we need a send() method to run the request:

xhr.send();

Fetch

The Fetch API is a modern alternative that can serve as a replacement for XHR. It was built to make asynchronous HTTP requests easy to do in JavaScript.

Let’s see a basic example of the syntax:

fetch(url) // Call the fetch function passing the url of the API as a parameter
.then(function() {
    // Your code for handling the data you get from the API
})
.catch(function() {
    // This is where you run code if the server returns any errors
});

All we are doing here is fetching the URL that we want, by default fetch uses the GET method — which is what we want in this case!

Let’s see some more fleshed out sample code:

fetch('http://example.com/songs.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(JSON.stringify(myJson));
  });

Here we are fetching a JSON file from the URL and then printing it to the console. The simplest use of fetch() takes one argument — the path to the resource you want to fetch — and returns a promise containing the response (in the form of a JavaScript object).

To extract the JSON body content from the response, we use the JSON.stringify(myJson)method. Then we can transform the response object into an object that we can interact with.

Working with promises

Like many modern JavaScript APIs, Fetch uses promises. Though they are a bit confusing at first, don’t worry too much about it for now. You’ll get used to them!

Let’s look at the promise structure as it relates to our Fetch request:

fetch('http://example.com/songs.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(JSON.stringify(myJson));
});

The first line is saying “fetch the resource located our URL” (fetch('http://example.com/songs.json')) and "then run the specified function when the promise resolves" (.then(function() { ... })). "Resolve" means "finish performing the specified operation at some point in the future".

The specified operation, in this case, is to fetch a resource from our specified URL (using an HTTP request) and return the response for us to do something with.

Effectively, the function passed into then() is a chunk of code that won't run immediately. Instead, it’ll run at some point in the future when the response has been returned.

So which technique should you use?

XHR has been around for a long time now and has very good cross-browser support. Fetch and Promises, on the other hand, are newer additions to the web platform, although they’re supported well across the browser landscape, with the exception of Internet Explorer.

If you need to support older browsers, then an XHR solution might be preferable. If however you are working on a more progressive project and aren’t as worried about older browsers, then Fetch would be a good choice.

Wrapping up

And that’s it! We looked at how to start working with AJAX using techniques such as XHR and Fetch to retrieve data from a server. And we looked at basic examples of each! Hopefully, now you have a grasp of each & can start incorporating async operations into your code!

Related Posts: