Handling JSON Responses0%

Handling JSON Responses

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Handling JSON Responses in Modern JavaScript

JavaScript Object Notation (JSON) is the universal data interchange format of modern web services. When receiving responses via the Fetch API, reading and parsing JSON safely requires understanding response body streams and error handling.


1. The response.json() Method

The HTTP response body returned by fetch() is a readable stream. To parse this stream into a native JavaScript object, invoke response.json():

JavaScript
async function loadUserData() {
const response = await fetch('https://api.github.com/users/octocat');
if (!response.ok) {
throw new Error(`Failed to fetch user: ${response.status}`);
}
 
// response.json() reads the stream to completion and parses JSON
const userData = await response.json();
console.log('Username:', userData.login);
console.log('Public Repositories:', userData.public_repos);
}
Output
Network Payload (Raw String) ──► ReadableStream ──► response.json() ──► Native JS Object

2. Response Body Streams Can Only Be Read ONCE!

A crucial architectural detail of the Fetch API is that the body stream can only be consumed once. Attempting to read it a second time throws a TypeError:

JavaScript
const response = await fetch('/api/data');
 
const json = await response.json(); // Consumed the stream!
// const text = await response.text(); // ERROR: TypeError: Failed to execute 'text' on 'Response': body stream already read!

The Solution: Cloning the Response

If you need to read the body multiple times (for example, for logging and parsing):

JavaScript
const response = await fetch('/api/data');
const clonedResponse = response.clone(); // Clones the stream before reading
 
const textDebug = await clonedResponse.text();
const jsonData = await response.json();

3. Safe Parsing: Handling Malformed JSON & Non-JSON Responses

If a server crashes and returns an HTML error page (e.g., 502 Bad Gateway from Nginx) instead of JSON, response.json() will throw a SyntaxError: Unexpected token < in JSON.

JavaScript
async function safeFetchJson(url) {
const response = await fetch(url);
const contentType = response.headers.get('content-type');
if (!contentType || !contentType.includes('application/json')) {
const rawText = await response.text();
throw new Error(`Expected JSON but received: ${contentType}. Content: ${rawText.slice(0, 100)}`);
}
 
try {
return await response.json();
} catch (parseError) {
throw new Error(`Failed to parse JSON payload: ${parseError.message}`);
}
}

4. Other Response Parsing Methods

Depending on the API format, Response provides multiple stream consumers:

MethodDecodes AsTypical Media Types
response.json()JavaScript Object / Arrayapplication/json
response.text()UTF-8 Stringtext/plain, text/html, text/csv
response.blob()Binary Large ObjectImages (image/png), PDFs, Audio files
response.formData()FormData Objectmultipart/form-data
response.arrayBuffer()Raw Binary BufferWebAssembly .wasm, low-level byte manipulation

Interactive Quiz

Practice Quiz

Question 1
What does response.json() return?
Question 2
What happens if you call both response.json() and response.text() on the same Response instance without cloning?
Question 3
Why does calling response.json() sometimes throw SyntaxError: Unexpected token '<'?
Question 4
Which method should you use on a Response object to download and display an image file?
Question 5
How can you check if the server declared the response payload as JSON?
Next Lesson

GET vs POST Requests

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext