Tutorial

How To Use the JavaScript Fetch API to Get Data

Updated on December 11, 2021
    authorauthor

    Sara Vieira and Ceora Ford

    English
    How To Use the JavaScript Fetch API to Get Data

    Introduction

    There was a time when XMLHttpRequest was used to make API requests. It didn’t include Promises, and it didn’t make for clean JavaScript code. Using jQuery, you could use the cleaner syntax of jQuery.ajax().

    Now, JavaScript has its own built-in way to make API requests. This is the Fetch API, a new standard to make server requests with Promises, but which also includes additional features.

    In this tutorial, you will create both GET and POST requests using the Fetch API.

    Deploy your frontend applications from GitHub using DigitalOcean App Platform. Let DigitalOcean focus on scaling your app.

    Prerequisites

    To complete this tutorial, you will need the following:

    Step 1 — Getting Started with Fetch API Syntax

    One approach to using the Fetch API is by passing fetch() the URL of the API as a parameter:

    fetch(url)
    

    The fetch() method returns a Promise. After the fetch() method, include the Promise method then():

    fetch(url)
      .then(function() {
        // handle the response
      })
    

    If the Promise returned is resolve, the function within the then() method is executed. That function contains the code for handling the data received from the API.

    After the then() method, include the catch() method:

    fetch(url)
      .then(function() {
        // handle the response
      })
      .catch(function() {
        // handle the error
      });
    

    The API you call using fetch() may be down or other errors may occur. If this happens, the reject promise will be returned. The catch method is used to handle reject. The code within catch() will be executed if an error occurs when calling the API of your choice.

    With an understanding of the syntax for using the Fetch API, you can now move on to using fetch() on a real API.

    Step 2 — Using Fetch to get Data from an API

    The following code samples will be based on the JSONPlaceholder API. Using the API, you will get ten users and display them on the page using JavaScript. This tutorial will retrieve data from the JSONPlaceholder API and display it in list items inside the author’s list.

    Begin by creating an HTML file and adding a heading and unordered list with the id of authors:

    authors.html
    <h1>Authors</h1>
    <ul id="authors"></ul>
    

    Now add script tags to the bottom of your HTML file and use a DOM selector to grab the ul. Use getElementById with authors as the argument:

    authors.html
    <h1>Authors</h1>
    <ul id="authors"></ul>
    
    <script>
      const ul = document.getElementById('authors');
    </script>
    

    Remember, authors is the id for the previously created ul.

    Next, create a list that is a DocumentFragment:

    authors.html
    <script>
      // ...
    
      const list = document.createDocumentFragment();
    </script>
    

    All the appended list items will be added to list. A DocumentFragment is not part of the active document tree structure. This has the benefit of not causing performance-affecting redraws when the Document Object Model is changed.

    Create a constant variable called url which will hold the API URL that will return ten random users:

    authors.html
    <script>
      // ...
    
      const url = 'https://jsonplaceholder.typicode.com/users';
    </script>
    

    Now using the Fetch API, call the JSONPlaceholder API using fetch() with url as the argument:

    authors.html
    <script>
      // ...
    
      fetch(url)
    </script>
    

    You are calling the Fetch API and passing in the URL to the JSONPlaceholder API. Then a response is received. However, 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. To convert the object returned into JSON, use the json() method.

    Add the then() method which will contain a function with a parameter called response:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {})
    </script>
    

    The response parameter takes the value of the object returned from fetch(url). Use the json() method to convert response into JSON data:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
    </script>
    

    The JSON data still needs to be processed. Add another then() statement with a function that has an argument called data:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {})
    </script>
    

    Within this function, create a variable called authors that is set equal to data:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          let authors = data;
        })
    </script>
    

    For each author in authors, you will want to create a list item that displays their name. The map() method is suited for this pattern:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          let authors = data;
    
          authors.map(function(author) {
    
          });
        })
    </script>
    

    Within your map function, create a variable called li that will be set equal to createElement with li (the HTML element) as the argument. Also, create an h2 for name and a span for email:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          let authors = data;
    
          authors.map(function(author) {
            let li = document.createElement('li');
            let name = document.createElement('h2');
            let email = document.createElement('span');
          });
        })
    </script>
    

    The h2 element will contain the name of the author. The span element will contain the email of the author. The innerHTML property and string interpolation will allow you to do this:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          let authors = data;
    
          authors.map(function(author) {
            let li = document.createElement('li');
            let name = document.createElement('h2');
            let email = document.createElement('span');
    
            name.innerHTML = `${author.name}`;
            email.innerHTML = `${author.email}`;
          });
        })
    </script>
    

    Next, connect these DOM elements with appendChild:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          let authors = data;
    
          authors.map(function(author) {
            let li = document.createElement('li');
            let name = document.createElement('h2');
            let email = document.createElement('span');
    
            name.innerHTML = `${author.name}`;
            email.innerHTML = `${author.email}`;
    
            li.appendChild(name);
            li.appendChild(email);
            list.appendChild(li);
          });
        })
    
      ul.appendChild(list);
    </script>
    

    Note that each list item is being appended to the DocumentFragment list. Once the map is complete, the list is appended to the ul unordered list element.

    With both then() functions completed, you can now add the catch() function. This function will log the potential error to the console:

    authors.html
    <script>
      // ...
    
      fetch(url)
        .then((response) => {
          // ...
        })
        .then((data) => {
          // ...
        })
        .catch(function(error) {
          console.log(error);
        });
    
      // ...
    </script>
    

    This is the full code of the request you created:

    authors.html
    <h1>Authors</h1>
    <ul id="authors"></ul>
    
    <script>
      const ul = document.getElementById('authors');
      const list = document.createDocumentFragment();
      const url = 'https://jsonplaceholder.typicode.com/users';
    
      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          let authors = data;
    
          authors.map(function(author) {
            let li = document.createElement('li');
            let name = document.createElement('h2');
            let email = document.createElement('span');
    
            name.innerHTML = `${author.name}`;
            email.innerHTML = `${author.email}`;
    
            li.appendChild(name);
            li.appendChild(email);
            list.appendChild(li);
          });
        }).
        .catch(function(error) {
          console.log(error);
        });
    
      ul.appendChild(list);
    </script>
    

    You just successfully performed a GET request using the JSONPlaceholder API and the Fetch API. In the next step, you will perform POST requests.

    Step 3 — Handling POST Requests

    Fetch defaults to GET requests, but you can use all other types of requests, change the headers, and send data. Let’s create a POST request.

    First, include a constant variable that holds the link to the JSONPlaceholder API:

    new-author.js
    const url = 'https://jsonplaceholder.typicode.com/users';
    

    Next, you need to set your object and pass it as the second argument of the fetch function. This will be an object called data with the key name and value Sammy (or your name):

    new-author.js
    // ...
    
    let data = {
      name: 'Sammy'
    }
    

    Since this is a POST request, you will need to state that explicitly. Create an object called fetchData:

    new-author.js
    // ...
    
    let fetchData = {
    
    }
    

    This object needs to include three keys: method, body, and headers:

    new-author.js
    // ...
    
    let fetchData = {
      method: 'POST',
      body: JSON.stringify(data),
      headers: new Headers({
        'Content-Type': 'application/json; charset=UTF-8'
      })
    }
    

    The method key will have the value 'POST'. body will be set equal to the JSON.stringify() format of the data object that was just created. headers will have the value of 'Content-Type': 'application/json; charset=UTF-8'.

    The Headers interface is a property of the Fetch API, which allows you to perform actions on HTTP request and response headers. This article called How To Define Routes and HTTP Request Methods in Express can provide you with more information.

    With this code in place, the POST request can be made using the Fetch API. You will include url and fetchData as arguments for your fetch POST request:

    new-author.js
    // ...
    
    fetch(url, fetchData)
    

    The then() function will include code that handles the response received from the JSONPlaceholder API:

    new-author.js
    // ...
    
    fetch(url, fetchData)
      .then(function() {
        // Handle response you get from the API
      });
    

    This is the full code of the request you created:

    new-author.js
    const url = 'https://jsonplaceholder.typicode.com/users';
    
    let data = {
      name: 'Sammy'
    }
    
    let fetchData = {
      method: 'POST',
      body: JSON.stringify(data),
      headers: new Headers({
        'Content-Type': 'application/json; charset=UTF-8'
      })
    }
    
    fetch(url, fetchData)
      .then(function() {
        // Handle response you get from the API
      });
    

    Alternatively, you can pass fetch() a Request object.

    new-author-request.js
    const url = 'https://jsonplaceholder.typicode.com/users';
    
    let data = {
      name: 'Sammy'
    }
    
    let request = new Request(url, {
      method: 'POST',
      body: JSON.stringify(data),
      headers: new Headers({
        'Content-Type': 'application/json; charset=UTF-8'
      })
    });
    
    fetch(request)
      .then(function() {
        // Handle response you get from the API
      });
    

    With this approach, request can be used as the sole argument for fetch(), replacing url and fetchData.

    Now you know two methods for creating and executing POST requests with the Fetch API.

    Conclusion

    While the Fetch API is not yet supported by all the browsers, it is a great alternative to XMLHttpRequest.

    If you would like to learn how to call Web APIs using React, check out this article on this very topic.

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about our products

    About the authors
    Default avatar
    Sara Vieira

    author



    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
     
    3 Comments
    

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    i created an account to say this. although the article is helpful the syntax highlighting is atrocious my eyes are bleeding please change the colors please

    Hey, Sara, thanks for the article. There are some minor typos in Step 2 full code so it doesn’t work. I´ve checked and change a little bit and now it´s ok:

    <h1>Authors</h1>

    <ul id="authors">
    
    </ul>
    

    <script> const ul = document.getElementById(‘authors’); const list = document.createDocumentFragment(); const url = ‘https://jsonplaceholder.typicode.com/users/’;

    fetch(url) .then((response) => { return response.json(); }) .then((json) => { json.map(function(author) { let li = document.createElement(‘li’); let name = document.createElement(‘h2’); let email = document.createElement(‘span’);

        name.innerHTML = `${author.name}`;
        email.innerHTML = `${author.email}`;
    
        li.appendChild(name);
        li.appendChild(email);
        list.appendChild(li);
        ul.appendChild(list);
      });
    })
    .catch(function(error) {
      console.log(error);
    });
    

    </script>

    I have may be a basic question, with the url, when I work on visual studio url it’s like https://localhost:3030/api/something but when I publish it’s like https://myserver:3030/api/something how can I handle this to avoid change url in all my functions because is hardcode basically

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Become a contributor for community

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    DigitalOcean Documentation

    Full documentation for every DigitalOcean product.

    Resources for startups and SMBs

    The Wave has everything you need to know about building a business, from raising funding to marketing your product.

    Get our newsletter

    Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

    New accounts only. By submitting your email you agree to our Privacy Policy

    The developer cloud

    Scale up as you grow — whether you're running one virtual machine or ten thousand.

    Get started for free

    Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

    *This promotional offer applies to new accounts only.