JavaScript's Fetch API offers a user-friendly interface for fetching resources, serving as the latest standard for handling network requests in web browsers.

One significant advantage of the Fetch API over XMLHttpRequest (XHR) is its utilization of promises, which simplifies the handling of requests and responses. It eliminates concerns about callback hell and the boilerplate code associated with XHR.

How to utilize the Fetch API?

The Fetch API provides the fetch() method, accessible in the global window scope, where the first parameter represents the URL to be called. By default, Fetch API initiates a GET request.

Here's a basic HTTP request using fetch():

// `url` - the URL to call
fetch(url)
  .then(res => {
    // code to handle the response data
  })
  .catch(err => {
    // code to handle request errors
  })

Doesn't it appear clean and straightforward? Now let's utilize the Fetch API to retrieve and post data.

Fetch API for retrieving data (GET)

To illustrate how a Fetch GET request works, let's make a call to the GitHub API to obtain a list of users. We'll use JavaScript to display this information on a web page.

First, let's set up the HTML, which requires a heading and an unordered list:

<h1>GitHub Users</h1>
<ul id="users"></ul>

Before invoking the fetch() method, let's retrieve the list element from the DOM, where we'll display the users' information:

// List Element
const ul = document.querySelector('#users')

// GitHub API URL
const url = 'https://api.github.com/users'

Now, let's perform the actual task by calling the Fetch API to obtain the list of users:

fetch(url)
  .then(res => {
    // code to handle the response
  })
  .catch(err => {
    // code to handle errors
  })

The fetch() method returns a promise that invokes the then() method with a response object when it is fulfilled. The response object provides several methods to handle the response as needed. Here are a few of these methods:

  • json() — Resolves the promise with a JSON object
  • text() — Resolves the promise with plain text
  • blob() — Resolves the promise with a Blob object
  • formData() — Resolves the promise with a FormData object

Invoking any of these methods creates a new promise. Since our API response is a JSON string, we'll utilize the json() method:

fetch(url)
  .then(res => res.json())
  .then(data => {
    // code to handle the response
  })
  .catch(err => {
    console.error('Error: ', err)
  })

Excellent! We've completed the Fetch API request section. Now, let's write some vanilla JavaScript code. We'll create two helper functions to append and create new elements:

// create an element
const createNode = elem => {
  return document.createElement(elem)
}

// append an element to parent
const appendNode = (parent, elem) => {
  parent.appendChild(elem)
}

We can now proceed to parse the JSON object, create list items, and append them to the unordered list:

// ...
.then(data => {
  // iterate over users
  data.map(user => {
    // create elements
    let li = createNode('li'),
      img = createNode('img'),
      span = createNode('span')
			
    img.src = user.avatar_url
    span.innerText = user.login
		
    // append elements
    appendNode(li, img)
    appendNode(li, span)
    appendNode(ul, li)
  })
})
// ...

The code above is self-explanatory. We iterate over each user, create a list item, an image, and a span for each user. We update the image source with the user's avatar URL and set the span text to the user's login. Finally, we append these elements to their respective parents. That's it!

In the browser, it will appear as follows (assuming some CSS from Bootstrap has been added):

GitHub Users

Here's the complete code for our Fetch request:

// create an element
const createNode = elem => {
  return document.createElement(elem)
}

// append an element to parent
const appendNode = (parent, elem) => {
  parent.appendChild(elem)
}

// List Element
const ul = document.querySelector('#users')

// GitHub API URL
const url = 'https://api.github.com/users'

// make the API call
fetch(url)
  .then(res => res.json())
  .then(data => {
    // iterate over users
    data.map(user => {
      // create elements
      let li = createNode('li'),
        img = createNode('img'),
        span = createNode('span')

      img.src = user.avatar_url
      span.innerText = user.login

      // append elements
      appendNode(li, img)
      appendNode(li, span)
      appendNode(ul, li)
    })
  })
  .catch(err => {
    console.error('Error: ', err)
  })

Utilizing Fetch API to send data (POST)

The Fetch API is not restricted to GET requests; it can handle various other types of requests (POST, PUT, DELETE, etc.) with custom request headers and the ability to post data. Here's an example of a POST request:

const url = 'https://reqres.in/api/users'

// post body data
const user = {
  first_name: 'John',
  last_name: 'Doe',
  job_title: 'Blogger'
}

// request options
const options = {
  method: 'POST',
  body: JSON.stringify(user),
  headers: {
    'Content-Type': 'application/json'
  }
}

// send POST request
fetch(url, options)
  .then(res => res.json())
  .then(res => console.log(res))

Instead of utilizing an object literal, we can create a request object with all the options and pass it to the fetch() method:

const url = 'https://reqres.in/api/users'

// post body data
const user = {
  first_name: 'John',
  last_name: 'Doe',
  job_title: 'Blogger'
}

// create request object
const request = new Request(url, {
  method: 'POST',
  body: JSON.stringify(user),
  headers: new Headers({
    'Content-Type': 'application/json'
  })
})

// pass request object to `fetch()`
fetch(request)
  .then(res => res.json())
  .then(res => console.log(res))

If you'd like to explore the Fetch API in-depth, you can refer to this article.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.