Javascript Fetch API

Last updated on February 20th, 2024 at 02:29 pm

Languages, frameworks, tools, and trends

The JavaScript Fetch API: Everything You Need to Know

By August 30, 2023 7 min read

fetch() is a mechanism that lets a user make simple AJAX (Asynchronous JavaScript and XML) calls with JavaScript. This means you can use this function to make a call without interrupting the execution of other operations. This article will explain what the fetch()  API does and how it is used. We will also explore different requests with fetch() and how to handle errors using code snippets to accelerate the learning process.

At the end of this tutorial, users will effectively be able to use GET and POST requests with fetch() in their JavaScript applications, understand how Fetch API is used to make asynchronous HTTP requests, and have the ability to handle errors efficiently.

Introduction

The JavaScript Fetch API is an interface that accesses and manipulates parts of the protocol (a system of rules that indicate how data is exchanged between or within computers), such as requests and responses. The JavaScript fetch interface acts as a means for fetching resources (including across the network). It also uses a global fetch() method that provides an easy, logical way to get resources asynchronously across networks. This method is also available when instructing web browsers to send a request to a URL.

Why is it important to use the JavaScript Fetch API?

The JS Fetch API has transformed the way developers make asynchronous requests in modern web applications.This fetch()  method is so incredible that one can initiate the process of fetching a resource from the network, which returns a promise fulfilled once the response is available. The promise can be found in the Response object, which represents the response to your request.

It is important to know that a  fetch() promise can only reject when there is a network error (this mostly occur during permissions issue or something similar). Also, a  fetch() promise does not reject on HTTP errors (404, etc.). However, if something like that is encountered, a then() handler must check the Response.ok and/or Response.status properties.

Another interesting thing about this global method is its connection with WindowOrWorkerGlobalScope, which is implemented by both Window and WorkerGlobalScope (an interface of the web worker API that represents the scope of any worker). This means that the fetch() method is available in any context that one might want to use in fetching resources.

How to supply request options using JavaScript Fetch API?

Basic Syntax

fetch(resource)
fetch(resource, options)

Parameters

resource

This defines the resource that is being fetched. This can be a string or a request object.

options

This is an object containing any custom settings that can be applied to the request. 

method

The request method, e.g., GET, POST. Note that the Origin header (a header that indicates the origin (scheme, hostname, and port) that caused the request.) is not set on fetch requests with a method of HEAD or GET.

headers.

Headers added to the request should be contained within a Headers object or an object literal with String values. Some names are forbidden to be used as headers.

body

A body can be a Blob, an ArrayBuffer, a TypedArray, a URLSearchParams, a DataView, a FormData, string object or literal, or a ReadableStream object. However, a request using the GET or HEAD method cannot have a body.

mode

This involves a mode that is used for the request, e.g., CORS (Cross-Origin Resource Sharing), no-cors, or same-origin.

credentials. This controls what browsers do with credentials (cookies, TLS client certificates and HTTP authentication entries). It must involve one of the following strings:

omit

This will tell the browser to exclude credentials from the request and ignore any credentials sent back in the response (e.g., any Set-Cookie header).

same-origin

As the default value, this will tell browsers to include credentials with requests to same-origin URLs and use any credentials sent back in responses from the same-origin URLs.

These are some of the parameters that are used when implementing the fetch() method in JavaScript.

Code Snippet

Let’s take a look at a practical JavaScript fetch example to see this API in action. A basic fetch request is really simple to set up. 

Here is a code snippet below;

fetch(‘http://example.com/movies.json’)
  .then((response) => response.json())
  .then((data) => console.log(data));

In the code above, we are fetching a JSON file across the network and printing it directly to the console. The simpler way to use fetch()  takes only an argument, which is the path to the resource one decides to fetch, and does not directly return the JSON response body but instead returns a promise that is fixed with a Response object.

The Response object, in turn, does not directly contain the JSON response body but serves as a representation of the entire HTTP response. So, to extricate this JSON response body from the Response object, we will use the json() method. This method returns a second promise which resolves with the result of parsing the response body text as JSON.

GET and POST requests with fetch()  

GET Requests

Without options, fetch will always act as a GET request. Assuming we request an external API to get some data (for instance, a blog post). For this, we will use a simple GET request.

Simply call  fetch()  with the endpoint URL as the argument like this:

fetch(‘https://developer.mozilla.org/en-US/docs/Web/API/fetch’);

The response body for this endpoint will be any information about this blog post:

{
userId: 1,
id: 1,
title: ‘A post by Mozilla’,
body: ‘The fetch API’,
};

Ultimately, we also want to get the response body. But the response object contains quite a lot of information beyond the body, including the status code, headers, and other information. (Note that the fetch API returns a promise. Because of this, we will nest a then() method, as stated earlier in this tutorial, to handle the resolution).

Since data returned from the API is in a JSON form. Conversion is needed to make the data simple for JavaScript to operate with. This was also stated earlier, we will use the json() method to achieve that:

fetch(‘ https://developer.mozilla.org/en-US/docs/Web/API/fetch’)
.then(data => {
return data.json();
})
.then(post => {
console.log(post.title);
});

POST Requests

In the above code, we nested a subsequent then() method to parse the data (in this case, is the title). We simply tried to get a blog post from the API in this example. Let us try to use a JavaScript fetch POST method to submit an article to the blog.

Here, we will need to set a few more options. So far, we have only given a single argument to fetch(),  which is the URL endpoint. For a POST request, we will pass an object of configuration options as a second argument. This optional object can take a lot of different parameters. However, only the necessary parameters should be used. While sending a POST request, we need to declare this method and pass some data to create the new blog post. Remember that this is a JSON data; hence, we need to set a header of Content-Type set to application/JSON. Finally, we will need the body to act as a single string of JSON data.

const update = {
title: ‘A blog post by Moxilla’,
body: ‘The fetch API’,
userId: 1,
};

const options = {
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify(update),
};

And then, the API call:

fetch(‘https://jsonplaceholder.typicode.com/posts’, options)
.then(data => {
   if (!data.ok) {
   throw Error(data.status);
   }
   return data.json();
   }).then(update => {
   console.log(update);
   // {
   //
   title: ‘A blog post by Moxilla’,
   //
   body: ‘The fetch API’,
   //
   userId: 1,
   //
   id: 101
   // };
   }).catch(e => {
   console.log(e);
   });

If the request is successful, we will get a response body containing the blog post object along with a new ID. The response will vary depending on how the API is set up. Fetch calls should be put together for easier access.

Handling Errors

Although the JavaScript Fetch API provides an ideal way to make network requests, it is very necessary to handle potential errors that occur during the process. In contrast to traditional AJAX calls that generate an error when an HTTP error is encountered, The Fetch API only rejects a promise when there is a network failure. This means that HTTP errors like 500 or 404 won’t cause the fetch promise to reject. Rather, they will resolve normally, and the responsibility will be on the developer to handle these appropriately.

Recognizing HTTP Errors

You can check the ok property of the Response object to detect HTTP errors. If it returns false, the request was unsuccessful.

E.g

fetch(‘https://example.com/data’)
   .then(response => {
   if (!response.ok) {
   throw new Error(‘Network response was not ok’);
   }
   return response.json();
   })
   .then(data => console.log(data))
   .catch(error => console.log(‘There was a problem with the fetch operation:’, error.message));

In the code example above, If an HTTP error occurs in the fetch request, it will throw an error and the catch block will handle it.

Handling Network Failures

Network failures like when the requested URL doesn’t exist or the user is offline, will cause the fetch promise to reject. We can catch these using a .catch() block.

E.g

fetch(‘https://fake-url.com’)
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log(‘Unable to fetch data:’, error));

In this example, the error message ‘Unable to fetch data’ will be logged if the fetch request fails due to a network issue.

Good practices to keep in mind while using fetch.

  • Always use .catch(): Make sure you always have a .catch() at the end of your fetch chains to handle any unexpected errors.
  • Clone the response: Considering the fact that the response of a fetch() request is a Stream object that can only be read once, remember to clone the response if you need to read it multiple times.
  • Provide user feedback: In a practical setting or real-world application, remember to always provide feedback to the user. Be it an error message if something goes wrong or a loading spinner during the fetch, user feedback is essential for a good user experience.

You can ensure that your application remains reliable and user-friendly even when things don’t go as planned by recognizing and handling errors efficiently.

Summary

With the fetch function in JavaScript, we can make simple API calls, a simple GET request with fetch, and a POST request where we need to pass along certain other parameters, including a configuration object effortlessly.  Fetch enables a user to create HTTP requests, which are easily handled using JavaScript Promises. Regarding handling asynchronous control flow, Promises are a massive step up compared to callbacks. This is especially true when there is a need to chain multiple requests, one after the other. At this point, any user who reads and implements this tutorial will be able to use the fetch API in JavaScript effectively.


FAQs

  1. Can I cancel a fetch request once it’s been initiated?

    Yes. The fetch API does not provide a built-in method for canceling requests, but you can integrate it with the AbortController interface to achieve this functionality. By passing an AbortSignal to a fetch request, you can later call the abort() method on the associated AbortController to cancel the request.
  2. How do I use fetch to handle various response formats, such as XML or plain text?

    In the article, we demonstrated how to handle JSON responses using the json() method on the Response object, but you can also handle different formats using other methods. For plain text, use the text() method, and for XML or other data types, you can use methods like arrayBuffer() or formData(), depending on the response type.
  3. Is it possible to track the progress of a fetch request, like uploading a large file?

    No. By itself, The fetch API does not have built-in progress event handlers like the older XMLHttpRequest. If you need to track progress, particularly for large uploads or downloads, you might consider using XMLHttpRequest or third-party libraries that offer this functionality.
  4. Can I use the JavaScript fetch API in older browsers?

    No, but Polyfills can provide compatibility. The fetch API is a recent addition to JavaScript, although many newer browsers support it, some older ones may not. It’s always a good idea to check browser compatibility if you’re targeting older or less common browsers. Alternatively, you can use polyfills like whatwg-fetch to ensure compatibility with older browsers.
  5. How do I handle multiple fetch requests at the same time?

    You can handle fetch requests simultaneously by using the Promise.all()method. This method takes an array of promises – in this case, fetch requests – and returns a new promise that resolves when all the promises in the array have been resolved. This is useful for instances where you need to wait for multiple requests to complete before proceeding.

Join a network of the world's best developers and get long-term remote software jobs with better compensation and career growth.

Apply for Jobs

Summary
The JavaScript Fetch API: Everything You Need to Know
Article Name
The JavaScript Fetch API: Everything You Need to Know
Description
fetch() is a mechanism that lets a user make simple AJAX (Asynchronous JavaScript and XML) calls with JavaScript. Keep reading to know more.
Author

Author

  • Chris Roland

    Chris Ebube Roland is a dedicated Software Developer, Technical Writer, and Open Source evangelist. He is fascinated with the Tech Development world and is dedicated to learning more about programming, software engineering, and computer science.

Comments (2)

Your email address will not be published

  • Dumebi
    Aug 31, 2023 at 6:31 pm

    Very comprehensive. I’ve had issues with using the fetch() method. Thanks!

  • Paul Allsopp
    Feb 12, 2024 at 9:13 pm

    Correction: “Because of this, we will nest a then() method”

    The then method is not nested, it is chained.