Fetch and Validate a Response

Fetch and Validate a Response

fetch requests a resource and returns a promise for a response. Check response.ok before parsing a success body. This runnable example uses a fixed Response, not a network request, so it teaches response handling with deterministic data.

Before this topic, review Read an Asynchronous Sequence if its terms are unfamiliar.

What you’ll learn

  • Explain fetch and validate a response through the school example.
  • Trace the shown operations and distinguish their result from displayed output.
  • Make the practice change and explain its consequence: The fixed JSON body contains the edited mark, which parsing reads as a number.

Work through the school example

This is JavaScript using language features and the host console. Read the initial values, then follow each operation to its displayed result. A declaration names a value, a function call performs an operation, and console.log displays its arguments.

JavaScript · school.js · complete example

async function report() {
  const response = new Response('{"marks":72}', { status: 200 });
  if (!response.ok) throw new Error("Request failed");
  const student = await response.json();
  console.log(student.marks);
}
report();

Expected output

72
Run in JavaScript compiler →

What is the Fetch API?

The Fetch API provides a modern, promise-based way to make HTTP requests in JavaScript. It's widely used to retrieve or send data to servers, commonly with REST APIs.

Why Use Fetch Instead of XMLHttpRequest?

  • Simpler syntax using Promises
  • More readable and maintainable
  • Built-in support for JSON
  • Used in both browser and server (Node.js with polyfills)

Example 1: Making a GET Request

Let's fetch some user data from a free public API called jsonplaceholder.typicode.com.

// Fetch user data (GET request)
fetch('https://jsonplaceholder.typicode.com/users/1')
  .then(response => response.json())
  .then(data => {
    console.log('User Data:', data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });
User Data: {
  id: 1,
  name: "Leanne Graham",
  username: "Bret",
  email: "Sincere@april.biz",
  ...
}

Question: What if the response is not a 200 OK?

Answer: The fetch promise does not reject on HTTP errors (like 404 or 500). You have to check response.ok to handle those cases manually.

Example 2: Handling Errors Gracefully

fetch('https://jsonplaceholder.typicode.com/invalid-url')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not OK');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('Fetch failed:', error.message);
  });
Fetch failed: Network response was not OK

Example 3: Sending a POST Request

Now let’s send some data to the server using POST method. This is useful for forms, comments, user creation, etc.

const postData = {
  title: 'Learn Fetch API',
  body: 'This is a POST request example.',
  userId: 101
};

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(postData)
})
  .then(response => response.json())
  .then(data => {
    console.log('Response from POST:', data);
  })
  .catch(error => {
    console.error('Error:', error);
  });
Response from POST: {
  title: "Learn Fetch API",
  body: "This is a POST request example.",
  userId: 101,
  id: 101
}

Question: Why use JSON.stringify for body?

Answer: Fetch expects the body to be a string, so we convert our JavaScript object to a JSON string before sending it.

Example 4: Async/Await Version

If you want cleaner and more readable syntax, use async/await.

async function getUser() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users/2');
    if (!response.ok) {
      throw new Error('Request failed');
    }
    const data = await response.json();
    console.log('User:', data);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

getUser();
User: {
  id: 2,
  name: "Ervin Howell",
  ...
}

Key Points to Remember

  • Fetch is Promise-based and cleanly supports then/catch or async/await
  • Always check response.ok to handle non-200 responses
  • Use JSON.stringify for sending objects in POST
  • Use Content-Type: application/json header for JSON requests

Recognize the important boundary

An HTTP 404 normally fulfills fetch with a response; it is not automatically a rejection. Real requests also face CORS, network failure and invalid response data.

After parsing a response, apply JSON field and range validation rather than assuming every successful response contains a valid student.

Try a small variation

JavaScript · original source for practice

async function report() {
  const response = new Response('{"marks":72}', { status: 200 });
  if (!response.ok) throw new Error("Request failed");
  const student = await response.json();
  console.log(student.marks);
}
report();

Your task: Replace "marks":72 with "marks":80. Predict the result before running the edited program.

The source is repeated here. If the edit targets the HTML rather than the script, use the markup repeated below; the worked answer also repeats the changed markup.

Worked answer and reasoning

The fixed JSON body contains the edited mark, which parsing reads as a number.

JavaScript · complete worked variation

async function report() {
  const response = new Response('{"marks":80}', { status: 200 });
  if (!response.ok) throw new Error("Request failed");
  const student = await response.json();
  console.log(student.marks);
}
report();

Expected output

80
Run in JavaScript compiler →

Predict the original program

JavaScript · original program for this question

async function report() {
  const response = new Response('{"marks":72}', { status: 200 });
  if (!response.ok) throw new Error("Request failed");
  const student = await response.json();
  console.log(student.marks);
}
report();
What does the original JavaScript program display, in order?
Choose one answer. You can try again.

Answer and explanation

72

fetch requests a resource and returns a promise for a response. Check response.ok before parsing a success body. This runnable example uses a fixed Response, not a network request, so it teaches response handling with deterministic data. An HTTP 404 normally fulfills fetch with a response; it is not automatically a rejection. Real requests also face CORS, network failure and invalid response data.

Check the important distinction

Does fetch automatically reject because the server returns HTTP 404?
Choose one answer. You can try again.

Answer and explanation

No. Check response.ok or status; network failures can reject.

A response can arrive successfully at the network level but describe HTTP failure.

Connect the response to a real request

This example makes a real same-origin HTTP request. Provide /__javascript-api/student on your own practice server with JSON such as {"marks":72}. This teaching endpoint is used by the verification server; it is not a public API on the deployed course. A successful response prints 72; HTTP and invalid-data failures enter catch.

For a POST, use fetch(endpoint, {method:"POST", headers:{"Content-Type":"application/json"}, body:JSON.stringify({marks:72})}). The endpoint must implement that contract. Do not retry writes without understanding duplicate processing.

JavaScript · browser · real HTTP request with a practice endpoint

async function loadReport() {
  try {
    const response = await fetch('/__javascript-api/student');
    if (!response.ok) throw new Error('HTTP ' + response.status);
    const student = await response.json();
    if (!Number.isFinite(student.marks)) throw new Error('Invalid mark');
    console.log(student.marks);
  } catch (error) { console.log(error.message); }
}
loadReport();

Expected output

72

Keep the useful idea

fetch requests a resource and returns a promise for a response. Check response.ok before parsing a success body. This runnable example uses a fixed Response, not a network request, so it teaches response handling with deterministic data.

Check your variation against this explanation: The fixed JSON body contains the edited mark, which parsing reads as a number.

Use the JavaScript array reference library for individual array operations and boundary tests to check a rule independently.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Catch an Asynchronous Failure →