W3docs

JavaScript Fetch API

The Fetch API is a modern JavaScript interface for making network requests with improved simplicity and flexibility compared to XMLHttpRequest.

The Fetch API is a key feature in JavaScript that lets you make network requests (download data, submit forms, talk to APIs) and returns a Promise. It is the modern replacement for the older XMLHttpRequest and pairs naturally with async/await. This guide covers the common patterns: GET and POST requests, inspecting the response, reading JSON and text, sending headers, and handling errors — using the free JSONPlaceholder API for runnable examples.

Understanding the Fetch API

The Fetch API is built for network communication and uses a promise-based system to retrieve resources. It's flexible enough to manage different data formats and complex requests, making it an excellent choice for developing web applications.

The basic signature is fetch(url, options). It returns a promise that resolves to a Response object as soon as the server responds with headers — before the body has finished downloading. You then read the body separately with a method like .json() or .text(), each of which returns its own promise.

A critical gotcha: fetch() only rejects on a network failure (no connection, DNS error, CORS block). It does not reject on HTTP error statuses like 404 or 500 — those still resolve successfully. You must check response.ok (or response.status) yourself.

Basic Usage of Fetch

Let's dive into a basic example of fetching data from a JSONPlaceholder post:

javascript— editable

This snippet fetches data from a specific post, demonstrating how Fetch returns a promise that resolves to the response of the request. The response is then parsed as JSON and output to the console.

Inspecting the Response

The Response object carries useful metadata before you even read the body. The most important properties are:

  • response.ok — a boolean that is true for status codes in the 200–299 range.
  • response.status — the numeric HTTP status code (e.g. 200, 404, 500).
  • response.statusText — the text message that goes with the status (e.g. "OK").
  • response.headers — a Headers object you can query with .get().
javascript— editable

Reading the Body: .json() vs .text()

The body of a response can be read in several formats. Each method returns a promise and can only be called once per response — the body is a stream that gets consumed:

  • response.json() — parses the body as JSON and resolves to a JavaScript object or array.
  • response.text() — resolves to the raw body as a string. Useful for plain text, HTML, or when you want to handle JSON parsing yourself.
  • response.blob() — resolves to a Blob, for binary data like images or files.
javascript— editable

Error Handling in Fetch

Handling errors is critical when working with network requests. Because fetch() does not throw on HTTP error statuses, the standard pattern is to check response.ok and throw your own error when it is false. Here's an example incorporating error handling:

javascript— editable

In this example, we check if the response is successful; if not, an error is thrown. The .catch() method catches any errors, maintaining the integrity of the application.

Implementing a POST Request

The Fetch API is not limited to GET requests; it's equally adept at handling POST requests to send data to a server. Pass a second argument with method, a body, and headers. When sending JSON, you must both serialize the body with JSON.stringify() and set the Content-Type header so the server knows how to parse it. Here’s how to create a new post with JSONPlaceholder:

javascript— editable

This code snippet demonstrates sending a POST request with JSON data, specifying the method, body, and headers. It illustrates the Fetch API's versatility in handling various request types.

Sending Custom Request Headers

Headers are how you tell the server about the request — the content type, the expected response format, or authentication credentials such as a bearer token. You can pass headers as a plain object, or build them with the Headers class for more control:

javascript— editable

Note: a request to another origin will only succeed if that server allows it via CORS. See Fetch: Cross-Origin Requests for how cross-origin rules affect headers and credentials.

Leveraging Async/Await with Fetch

For a more elegant approach to asynchronous code, the Fetch API can be combined with async and await. This method offers a more readable syntax, akin to synchronous code:

javascript— editable

Using async and await, this example fetches a post, awaiting the response and processing it within a try/catch block for error handling. It showcases how modern JavaScript features can simplify Fetch API usage.

Handling Errors with Async/Await

When it comes to error handling in async/await, it's typically done using try-catch blocks.

To handle errors that may occur during asynchronous operations, you can wrap your await calls within a try block and catch any errors that occur with a catch block. Here's how you can add error handling to the fetchData function:

javascript— editable

Error Propagation

Error propagation is how an error "moves" or gets passed along from one part of your program to another. Think of it as the path an error takes after it happens. When an error occurs, it’s like dropping a ball. Error propagation is about where the ball goes after it’s dropped: does someone catch it, or does it hit the ground?

In JavaScript, this typically occurs through promise rejection chaining, where an unhandled rejection travels up the call stack until a catch block or global handler intercepts it.

In the example below, if you want errors to be handled by the caller function (like viewData), you should either avoid catching them in fetchData or rethrow them after catching:

javascript— editable

As you can see, the same error object is caught in both functions because we rethrow it from fetchData to viewData.

To go further with the Fetch API, explore these related chapters:

Conclusion

The Fetch API is an indispensable tool for JavaScript developers, enhancing web applications with its promise-based approach to network requests. Through practical examples, this guide demonstrates how the Fetch API can be effectively utilized for fetching data, handling errors, and making POST requests, leveraging the JSONPlaceholder API for real-world applications. Mastering the Fetch API empowers developers to create more responsive, dynamic, and robust web applications.

Practice

Practice
Which of the following statements about the Fetch API in JavaScript are true?
Which of the following statements about the Fetch API in JavaScript are true?
Was this page helpful?