SKU // 121

JSON Fetch

Most JSON in the real world sits on a server, or in a file on one, and fetch is how a page asks for it. This lesson puts the two together: request some JSON, check that the request worked, read it with response.json(), and use the data. It builds on the promises, async and await from Debugging Async.

About the examples. In the Try It editor, a name like "students.json" points to a small sample file kept beside the editor. On your own site you would use the path to your own file or the address of a web API.

// Two Steps: the Response, Then the Body

fetch(url) does not hand you the data. It gives you a Response as soon as the server answers. The body of the response is a separate step, because it can be large and arrives in pieces:

Piece What it gives you
fetch(url)a promise of a Response object
response.json()a promise of the body, parsed as JSON
response.text()a promise of the body as a plain string
response.oktrue for a successful status (200 to 299)
response.statusthe status number, like 200 or 404

// Your First JSON Fetch

fetch("students.json")
  .then(response => response.json())
  .then(students => {
    console.log(students.length);
    console.log(students[0].name);
  });
4 Ava

Each .then waits for the step before it. The first one returns response.json(), which is itself a promise, and the next .then receives its result: the parsed array.

// The Same Thing with async and await

await inside an async function reads top to bottom, which many people find easier to follow:

async function averageScore(name) {
  const response = await fetch("students.json");
  const students = await response.json();
  const student = students.find(s => s.name === name);
  const total = student.scores.reduce((sum, n) => sum + n, 0);
  return total / student.scores.length;
}

averageScore("Ava").then(average => console.log(average));
85

An async function always returns a promise, so the caller uses .then (or its own await) to get the result.

// response.json() Does the Parsing for You

You never have to call JSON.parse yourself. response.json() is the same as reading the text and parsing it, in one step:

fetch("products.json")
  .then(response => response.text())
  .then(text => {
    console.log(typeof text);
    const data = JSON.parse(text);
    console.log(data.items.length);
  });
string 3

// Check response.ok First

A missing file is not an error to fetch: the server still answers, with a status of 404 and an error page as the body. If you call response.json() on that page, you get a confusing SyntaxError, because the error page is not JSON. Check response.ok before you read the body, and throw your own clear error:

async function load(url) {
  const response = await fetch(url);
  console.log(response.status, response.ok);
  if (!response.ok) {
    throw new Error("Could not load " + url);
  }
  return response.json();
}

async function main() {
  try {
    const shop = await load("products.json");
    console.log(shop.store);
    await load("missing.json");
  } catch (error) {
    console.log(error.message);
  }
}

main();
200 true Lab Shop 404 false Could not load missing.json
fetch only rejects when it cannot ask
The promise from fetch rejects only when the request itself fails (no network, a blocked address). A 404 or 500 from a working server still resolves normally, so catch will not run unless you throw yourself.

// Check What Came Back

A server tells the browser what kind of data it is sending in the Content-Type header. JSON should arrive as application/json:

fetch("students.json").then(response => {
  console.log(response.headers.get("content-type"));
});
application/json

// Using the Data

Once response.json() finishes, you have ordinary objects and arrays, so everything from the Arrays section works: filter, map, reduce, find, loops.

async function inStockValue() {
  const response = await fetch("products.json");
  const shop = await response.json();
  const inStock = shop.items.filter(item => item.inStock);
  const total = inStock.reduce((sum, item) => sum + item.price, 0);
  console.log(inStock.map(item => item.name).join(", "));
  console.log(total.toFixed(2));
}

inStockValue();
Pen, Notebook 7.25

// Sending JSON to a Server

Fetch can also send data. Set the method to POST, tell the server you are sending JSON in the header, and put the stringified data in the body:

fetch("/api/scores", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Ava", score: 95 })
});

There is no Try It button for this one because it needs a server that accepts the data. The JS Fetch API lesson looks at requests in more detail.

// One More Rule: Other Websites

A page can read JSON from its own site freely. Reading from a different site works only if that site's server says it allows it (this is called CORS). If it does not, the browser blocks the response and fetch fails with TypeError: Failed to fetch, and the console explains that the request was blocked by CORS policy. It is a browser safety rule, not a bug in your code.

// Common Mistakes

// Quick Check

What does response.json() return?

  1. The parsed data, immediately
  2. A promise of the parsed data
  3. The raw JSON text
  4. The status code
Show answer
B. It returns a promise, so you use await or .then to get the parsed data.

A fetch for a file that does not exist gives a 404. Does the catch of a try...catch run on its own? Why?

Show answer
No. fetch rejects only when it cannot make the request at all. A 404 is still a response, so you must check response.ok and throw an error yourself.

What is missing?

async function load() {
  const response = await fetch("students.json");
  const students = response.json();
  console.log(students.length);
}
Show answer
An await before response.json(). Without it, students is a promise, and students.length is undefined.

// Try It

  1. Click Open Playground and run it. Which line prints first, and why?
  2. Change the Playground to fetch products.json and log the name of every item that costs more than 3
  3. Fetch students.json and log the names of students whose grade is 10
  4. Ask for a file that does not exist and handle the failure with a clear message
// Video Walkthroughs
Last updated: Oct 11, 2026, 5:59 PM ET