The Fetch API is a JavaScript API for making asynchronous HTTP requests in the browser, similar to XMLHttpRequest (XHR). It provides a promise-based and clean interface for fetching resources from a server.

The Fetch API is widely supported by modern browsers, except for Internet Explorer (IE). If you require IE support, you can include a polyfill.

Using the Fetch API

Using the Fetch API is straightforward. Simply pass the URL or path to the resource you want to fetch to the fetch() method:

fetch('/js/users.json')
  .then(response => {
    // handle the response data
  })
  .catch(error => {
    // handle errors
  })

The fetch() method returns a promise that resolves to the response object when the request is fulfilled. You can use the then() method to handle the response data and the catch() method to handle errors.

Making a GET request

By default, the Fetch API uses the GET method for asynchronous requests. Here's an example of retrieving a list of users from the Reqres REST API using a GET request:

fetch('https://reqres.in/api/users')
  .then(response => response.json())
  .then(data => {
    data.data.forEach(user => {
      console.log(`${user.id}: ${user.first_name} ${user.last_name}`)
    })
  })

The above code fetches the list of users and logs their information to the console.

Making a POST request

The Fetch API allows you to use various HTTP methods, including POST, PUT, DELETE, HEAD, and OPTIONS. To make a POST request, you need to set the method and body parameters in the fetch() options:

const user = {
  first_name: 'John',
  last_name: 'Doe',
  job_title: 'Software Engineer'
}

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

fetch('https://reqres.in/api/users', options)
  .then(response => response.json())
  .then(data => console.log(data))

In the above example, we send a POST request to create a new user and log the response data.

Making a DELETE request

A DELETE request is similar to a POST request, but the body parameter is not required:

const options = {
  method: 'DELETE',
  headers: {
    'Content-Type': 'application/json'
  }
}

fetch('https://reqres.in/api/users/2', options)
  .then(res => {
    if (res.ok) {
      return Promise.resolve('User deleted.')
    } else {
      return Promise.reject('An error occurred.')
    }
  })
  .then(res => console.log(res))

In this example, a DELETE request is made to delete a user with the ID 2. The response is checked, and a corresponding message is logged.

Handling errors

Error handling with the Fetch API is straightforward. You can use the catch() method to intercept any errors thrown during the request execution. However, it's important to note that the Fetch API doesn't reject HTTP errors by default. To handle HTTP errors, you can check the ok property of the response object:

fetch('https://reqres.in/api/users/22')
  .then(response => {
    if (response.ok) {
      return response.json()
    } else {
      throw new Error('Request failed with status ' + response.status)
    }
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error))

In the above example, if the response is not successful (HTTP status code outside the range of 200-299), an error is thrown and caught in the catch() block.

Customizing request headers

The Fetch API allows you to set, remove, or retrieve HTTP request headers using the Headers object. You can create a Headers object and use its methods to modify request headers:

// create an empty `Headers` object
const headers = new Headers()

// add headers
headers.append('Content-Type', 'text/plain')
headers.append('Accept', 'application/json')

// add custom headers
headers.append('X-AT-Platform', 'Desktop')
headers.append('X-AT-Source', 'Google Search')

// check if the header exists
headers.has('Accept') // true

// get headers
headers.get('Accept') // application/json
headers.get('X-AT-Source') // Google Search

// update header value
headers.set('Content-Type', 'application/json')

// remove headers
headers.delete('Content-Type')
headers.delete('X-AT-Platform')

You can pass an object literal or an array of arrays to the Headers constructor to create a header object. Here's an example:

// Passing an object literal
const headers = new Headers({
  'Content-Type': 'application/json',
  Accept: 'application/json'
})

// OR

// Passing an array of arrays
const headers = new Headers([
  ['Content-Type', 'application/json'],
  ['Accept', 'application/json']
])

In both cases, the headers object will contain the specified headers.

To include these headers in the request, you can create a Request instance and pass it to the fetch() method. Here's an example:

const request = new Request('https://reqres.in/api/users', {
  headers: headers
})

fetch(request)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('Error:', err))

In this example, the Request object is created with the headers option set to the headers object we created earlier. Then, the Request object is passed as the first argument to the fetch() method. This ensures that the specified headers are included in the request.

By using the Request object, you have more control over the request and can customize various aspects, including headers, method, body, and more.

Sending cookies

To send cookies with a Fetch request, you can enable credentials by including the credentials: 'include' option in the request configuration. Here's an example:

fetch(url, {
  credentials: 'include'
})

By setting credentials to 'include', the request will include any cookies associated with the requested domain.

Using async-await

The usage of async/await with Fetch is indeed a powerful combination that allows you to write asynchronous code in a more synchronous-like manner. The following example demonstrates how to use async/await with Fetch to simplify the code and handle errors gracefully.

const fetchUsers = async () => {
  try {
    const res = await fetch('https://reqres.in/api/users')
    if (!res.ok) {
      throw new Error(res.status)
    }
    const data = await res.json()
    console.log(data)
  } catch (error) {
    console.log(error)
  }
}

fetchUsers()

By marking the function as async and using await before the Fetch call and res.json(), the code waits for the promises to resolve and behaves in a more synchronous manner.

Conclusion

In conclusion, the Fetch API provides a modern and convenient way to make HTTP requests in JavaScript, and the combination of enabling credentials and using async/await can enhance the functionality and readability of your code.

If you're interested in learning about making HTTP requests using the older XMLHttpRequest object, you can refer to this article.

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