100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
JavaScript

Fetch API in JavaScript

Use the Fetch API to make HTTP requests, and learn the critical gotcha that fetch does not reject on HTTP error status codes.

Asynchronous JavaScriptIntermediate10 min readJul 8, 2026
Analogies

1. Introduction

The Fetch API is the modern, Promise-based interface for making HTTP requests in JavaScript, replacing the older XMLHttpRequest. It is built into browsers and, since Node.js 18, is also available globally in Node without any extra library. Calling fetch(url) returns a Promise that resolves to a Response object once the HTTP response headers have been received, and you then read the body (as JSON, text, etc.) using further Promise-returning methods like response.json().

🏏

Cricket analogy: Calling fetch(url) is like sending a runner to fetch the scoreboard update -- you get confirmation (the Response) once the runner reaches the board, but you still need a second trip, like response.json(), to actually read the detailed over-by-over figures.

2. Syntax

javascript
// Basic GET request
const response = await fetch("https://api.example.com/users/1");
const data = await response.json();

// POST request with a JSON body
const response2 = await fetch("https://api.example.com/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Alice" }),
});

// Checking for HTTP errors -- fetch does NOT do this for you
if (!response.ok) {
  throw new Error(`HTTP error: ${response.status}`);
}

3. Explanation

fetch() returns a Promise, so it naturally fits async/await and .then() chaining. However, the single most important gotcha is this: fetch's returned Promise only rejects on a NETWORK failure (DNS failure, connection refused, CORS block, offline, etc.) -- it does NOT reject just because the server responded with an error status like 404 Not Found or 500 Internal Server Error. Those still count as a 'successful' fetch, because a valid HTTP response was received. To detect an HTTP-level failure, you must explicitly check response.ok (true for status codes 200-299) or inspect response.status yourself, and throw/handle the error manually.

🏏

Cricket analogy: fetch() only 'appeals unsuccessful' (rejects) if the ball never reaches the umpire at all, like a broken stump-mic (network failure) -- a wrong decision like a wrongly given out (404/500) still counts as a completed review that you must manually check via response.ok.

Forgetting to check response.ok is one of the most common real-world bugs with fetch. Code that does const data = await response.json(); if (data.error) ... will often still 'succeed' at parsing an error payload as if it were valid data, silently masking a 404 or 500. Always check response.ok (or response.status) before trusting the parsed body.

4. Example

This example mocks fetch with a Promise-based function (so it runs anywhere, without a real network) to demonstrate that a 404 response still resolves successfully -- it must be checked manually.

🏏

Cricket analogy: Just as a scoreboard operator can simulate a 'no result' match outcome on a practice board without a real stadium, this example mocks fetch to show a 404 still resolves normally -- you must check it yourself, like double-checking the scoreboard reading.

javascript
async function mockFetch(url) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        ok: false,
        status: 404,
        json: async () => ({ error: "Not Found" }),
      });
    }, 50);
  });
}

async function loadData(url) {
  try {
    const response = await mockFetch(url);
    console.log("Fetch completed, status:", response.status);
    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }
    const data = await response.json();
    console.log("Data:", data);
  } catch (err) {
    console.log("Caught error:", err.message);
  }
}

console.log("Start");
loadData("/api/user/999");
console.log("End");

5. Output

text
Start
End
Fetch completed, status: 404
Caught error: HTTP error: 404

6. Key Takeaways

  • fetch() returns a Promise that resolves to a Response once headers arrive; it works naturally with async/await.
  • fetch's Promise rejects ONLY on network-level failures, never merely because of an HTTP error status code.
  • Always check response.ok (or response.status) before treating the response as successful.
  • Reading the body (response.json(), response.text()) is itself an additional asynchronous step returning its own Promise.
  • Since Node.js 18, fetch is available globally without any extra package.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#JavaScriptProgrammingStudyNotes#Programming#FetchAPIInJavaScript#Fetch#API#Syntax#Explanation#APIs#StudyNotes#SkillVeris