JavaScript + Node.js track

Lesson 21 · Part 6: Browser APIs

Fetch & JSON

`fetch`, `JSON.parse`/`stringify` and error handling

Part 6: Browser APIs2 min readFree lesson

Level: Advanced | Players: 20_Asynchronous_Basic

Learning Objectives

  • You can send HTTP requests to the fetch() API.
  • JSON strings and objects can be converted.
  • Network errors and HTTP errors can be handled separately.
  • You can write fetch code concisely with async/await.

1. What is fetch?

It is an HTTP client built into browsers (and Node 18+). Returns a Promise.

fetch('https://jsonplaceholder.typicode.com/users/1')
  .then((res) => res.json())
  .then((user) => console.log(user.name));

res.json() parses the response body into JSON and returns a Promise.

2. JSON.parse / JSON.stringify

JSON is a data representation string. Used when converting to and from JS objects.

const obj = { name: 'Yi Sun-sin', age: 35 };
const str = JSON.stringify(obj);   //'{"name":"Yi Sun-shin","age":35}'
const back = JSON.parse(str);      //{ name: 'Yi Sun-shin', age: 35 }

3. POST request

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ title: 'hi', body: 'hello', userId: 1 }),
}).then((res) => res.json());

4. Error handling

fetch does not reject 4xx/5xx. You'll have to check res.ok for yourself.

fetch(url)
  .then((res) => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .catch((err) => console.error('Failure:', err));

Network disconnection is rejected.

5. async/await rewrite

async function loadUser(id) {
  const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

Core example

file Contents covered
01_get_json.js GET requests and JSON parsing
02_post_json.js Sending JSON with POST
03_error_handling.js res.ok / try-catch
04_async_await.js async/await rewrite

⚠️ Common Mistakes

  1. Forget calling res.json() and use the response object itself.
  2. Mistaking 4xx response as success — missing res.ok check.
  3. Omitting the Content-Type header from POST.
  4. Pass the object as is to body (must be JSON.stringify).
  5. Use await outside the async function.

❓ Frequently Asked Questions (FAQ)

Q1. Is fetch available in Node? A. It can be used globally starting from Node 18. Q2. Is XMLHttpRequest no longer used? A. Only when compatibility is required. New code uses fetch. Q3. Why CORS errors? A. Servers from other origins must allow it. This is a server-side setup issue.

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

src/01_get_json.jsJavaScript
/**
 *Receiving JSON data with GET request
 */
fetch('https://jsonplaceholder.typicode.com/users/1')
  .then((res) => res.json())
  .then((user) => {
    console.log('Name:', user.name);
    console.log('Email:', user.email);
  });
src/02_post_json.jsJavaScript
/**
 *Send JSON with POST request
 */
const newPost = {
  title: 'hello fetch',
  body: 'Body content',
  userId: 1,
};

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(newPost),
})
  .then((res) => res.json())
  .then((created) => console.log('Created:', created));
src/03_error_handling.jsJavaScript
/**
 *fetch error handling: res.ok and catch
 */
fetch('https://jsonplaceholder.typicode.com/users/9999')
  .then((res) => {
    if (!res.ok) {
      throw new Error(`HTTP ${res.status}`);
    }
    return res.json();
  })
  .then((data) => console.log(data))
  .catch((err) => console.error('Failure:', err.message));
src/04_async_await.jsJavaScript
/**
 *Rewritten with async/await
 */
async function loadUser(id) {
  const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

(async () => {
  try {
    const user = await loadUser(2);
    console.log(user.name);
  } catch (err) {
    console.error(err);
  }
})();

Assignment

Assignment 1

https://jsonplaceholder.typicode.com/users Get all users and print only their names to the console. Use async/await.

Assignment 2

When you click the button on the HTML page, receive one post and display it on the screen.

  • Endpoint: https://jsonplaceholder.typicode.com/posts/1
  • Display <h2> title, <p> body.
Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

homework_01.jsJavaScript
/**
 *Task 1: Print a list of user names
 */
async function listUserNames() {
  const res = await fetch('https://jsonplaceholder.typicode.com/users');
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const users = await res.json();
  users.forEach((u) => console.log(u.name));
}

listUserNames().catch((err) => console.error(err));
homework_02.htmlHTML
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
<title>Task 2 — Loading posts</title>
  </head>
  <body>
<button id="load">Load post</button>
    <div id="result"></div>
    <script src="homework_02.js"></script>
  </body>
</html>
homework_02.jsJavaScript
/**
 *Task 2: Display 1 post when button is clicked
 */
document.getElementById('load').addEventListener('click', async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  if (!res.ok) {
    alert(`HTTP ${res.status}`);
    return;
  }
  const post = await res.json();
  const box = document.getElementById('result');
  box.innerHTML = '';
  const h2 = document.createElement('h2');
  h2.textContent = post.title;
  const p = document.createElement('p');
  p.textContent = post.body;
  box.append(h2, p);
});

Learn this lesson with a mentor

Work through the JavaScript + Node.js track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now