JavaScript: Using fetch to make HTTP requests

Once upon a time JavaScript was used to add a small sprinkling of interactivity to otherwise static web pages. Times have changed since then. People now expect entire applications delivered in the browser. Applications need data, and the best way to get data to a Frontend app is to make HTTP calls to a web server.

In this tutorial, I will teach you the best way to make these HTTP requests in the browser via JavaScript. The fetch API.

Once upon a time JavaScript used to make web requests using XMLHttpRequest. If you want to know why I recommend fetch instead of this, look it up after reading this. It’s verbose and generally less straight forward than fetch.

Let’s use fetch to query the Giphy API, and get us some animated gifs!

If you want to follow along you’ll need to sign up at https://developers.giphy.com/ to get an API key first. You just signup, create a new app, and get the key. It’s probably worth looking at the docs for the search endpoint too, as that’s what we’re going to be using.

We’re going to be using fetch to search the giphy API for 5 Dalek giphys. We’ll then display them on the webpage.

First let’s make the url.

const url = 'https://api.giphy.com/v1/gifs/search?'
  + 'api_key=YOUR_API_KEY_GOES_HERE'
  + '&q=dalek'
  + '&limit=5'
  + '&offset=0'
  + '&rating=G'
  + '&lang=en';

It’s just a simple url of the giphy search endpoint, and query string params to configure the search as follows:

  • api_key: your api key, duh
  • q: string – the term to search for
  • limit: number – the maximum number of results to return
  • offset: number – skip all results before this offset. Used in conjunction with limit to allow for pagination
  • rating: string – how naughty it can be
  • lang: string – the language

To make a fetch request to this url we simply do:

fetch(url)

By default this will make a fetch request to this url. Fetch comes with many options including request type and headers, but we aren’t looking at those now.

The call to fetch will return a promise. If the promise resolves successfully (there is no error) then the function you pass to then will contain a response object.

The response object is an abstraction over an HTTP response. It contains a lot of stuff, but we’re only concerned with one part of it, the response body. The body is where giphy puts the data about the search results. It gives us this data as JSON. We can tell the response object to parse this json to a JavaScript object and give it to us using the .json() function on the response. The result of this will also return a promise.

fetch(url)
  .then(res => res.json())

This means that the result of the call to then() will also be a promise, and this promise will resolve to a JavaScript object containing the result of the search. Giphy gives us an object containing a property data, which as an array of all the search results.

If you console.log data out you’ll see the search results themselves are a huge object. I’m just going to show you an example of what we get back, including only one result, and only the properties we need from it:

const resultsWillLookLike = {
  data: [{
    images: {
      downsized: {
         url: 'http://media.giphy.com/result123.gif'
      }
    }
  }]
};
    

The part we are interested in is just the url of a downsized version of the giphy.

Let’s map over each result in data, and have the map iterator function create an IMG tag and add it to the webpage. We should end up with 5 giphys of Daleks on a webpage.

Here’s the full code:

function renderGiphy (giphy) {
  const img = document.createElement('IMG')
  img.src = giphy.images.downsized.url
  document.body.appendChild(img);
}

const url = 'https://api.giphy.com/v1/gifs/search?'
  + 'api_key=YOUR_API_KEY_GOES_HERE'
  + '&q=dalek'
  + '&limit=5'
  + '&offset=0'
  + '&rating=G'
  + '&lang=en';

fetch(url)
  .then(res => res.json())
  .then(({ data }) => data.map(renderGiphy));

2 comments

  1. What is the difference of using .then or async await? Can I use whichever I want with no difference or there are situations where is better to use one or another?

    I understand that in this example we can’t use “await” because that only works inside an async function, but I could use “.then” inside a function if I want to, so I don’t fully understand which one is a better way to work.

    These days I made a page to practice how to get data from an API and I discovered hell when I combined async functions with for loops. So I imagine that maybe I could avoid that horrible thing if I use “.then” in some cases, I will practice that to see what happens.

    This is the page if you want to check it out https://portfolio.bernardoayala.com/examples/book-store/

    And this is my humble code:
    https://github.com/nardoyala/book-store-homepage/blob/master/js/bookCovers.js

    1. Await will just ‘pause’ the function until the promise has resolved, and throw an exception if it’s rejected. It allows you to use promises without the need for callbacks so the code is simpler.

      So with promises:

      function doApiStuff () {
      fetch(url).then((response) => updateDOM(response)).catch((e) => logError(e));
      }
      doApiStuff();

      With async

      async function doApiStuff () {
      try {
      const data = await fetch(url);
      updateDOM(data);
      } catch (e) {
      logError(e);
      }
      }
      doApiStuff();

      Both do the same thing, but many would say the async version is simpler because it’s more imperative in style.

      Just think of await as ‘wait for this promise to resolve, then carry on’.

Leave a Reply

Your email address will not be published. Required fields are marked *