Now that you can make fetch requests, you need to understand what comes back. Almost every APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. on the internet speaks JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it., it's the universal language of data exchange. This lesson covers how to work with it fluently.
What JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. actually is
JSON (JavaScript Object Notation) looks almost exactly like a JavaScript object literal, but there are important differences. JSON is a string format, a text representation of data. It is not a JavaScript object. It cannot hold functions, undefined values, or real Date objects.
// A JavaScript object (in memory)
const user = {
name: 'Alice',
age: 30,
isActive: true
};
// Convert to a JSON string (for sending over the network or storing)
const jsonString = JSON.stringify(user);
// Result: '{"name":"Alice","age":30,"isActive":true}'
// Convert back from a JSON string to a JavaScript object
const parsedUser = JSON.parse(jsonString);
// Result: { name: 'Alice', age: 30, isActive: true }Think of JSON.stringify and JSON.parse as packing and unpacking a box. You pack your object into a flat text string to ship it, and unpack it on the other end to use it again.
Reading JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. from an APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. response
When you call response.json(), it reads the raw text of the response body and runs JSON.parse() on it for you. The result is a real JavaScript object you can work with immediately.
const response = await fetch('https://api.example.com/user/1');
const user = await response.json();
// user is now a plain JavaScript object
console.log(user.name); // 'Alice'
console.log(user.email); // 'alice@example.com'response.json() returns a Promise, so you must await it. If you forget, you'll have a Promise object instead of your data.What survives the JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. round trip
Not everything can be serialized to JSON and back. This is a common source of subtle bugs, especially when AI generates code that assumes Date objects survive.
| Value type | After JSON.stringify → JSON.parse | Survives? |
|---|---|---|
| Strings, numbers, booleans | Preserved exactly | Yes |
null | Preserved | Yes |
| Arrays, plain objects | Preserved (recursively) | Yes |
undefined | Property removed entirely | No |
| Functions | Removed entirely | No |
Date objects | Converted to ISO string ("2024-01-15T...") | Partial |
Map, Set | Converted to empty object {} | No |
Infinity, NaN | Converted to null | No |
const data = {
name: 'Alice',
createdAt: new Date('2024-01-15'),
callback: () => console.log('hi'),
metadata: undefined
};
const parsed = JSON.parse(JSON.stringify(data));
// { name: 'Alice', createdAt: '2024-01-15T00:00:00.000Z' }
// callback and metadata are gone, createdAt is now a stringresponse.json() in a try/catch, so when a server returns HTML (like an error page) or plain text, the app crashes with an unhelpful SyntaxError: Unexpected token < in JSON. Always consider that parsing might fail.Sending JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. in a request body
When you POST or PUT data to an APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses., you need to manually stringify your object and set the Content-Type header so the server knows what format it's receiving.
const newUser = {
name: 'Bob',
email: 'bob@example.com'
};
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json' // Required: tell the server what's coming
},
body: JSON.stringify(newUser) // Required: convert object to string
});
const createdUser = await response.json();Missing either the header or the JSON.stringify call are the two most common mistakes when sending data. The header tells the server how to interpret the body; the stringify converts your object into something that can actually travel over the wire as text.
Navigating complex JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. structures
Real APIs rarely return flat objects. You'll deal with nested objects, arrays of objects, and arrays nested inside objects.
// Nested objects
const data = {
user: {
id: 1,
profile: {
name: 'Alice',
settings: { theme: 'dark' }
}
}
};
const theme = data.user.profile.settings.theme; // 'dark'// Arrays of objects (very common in API responses)
const response = await fetch('https://api.example.com/posts');
const posts = await response.json(); // posts is an Array
posts.forEach(post => console.log(post.title));
const specificPost = posts.find(p => p.id === 5);data.user is null or undefined, accessing data.user.profile will throw. Use optional chaining (data.user?.profile?.settings?.theme) when a field might be absent.Parsing JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. safely
JSON.parse() throws if the input is not valid JSON. If you're parsing untrusted input (from localStorage, a legacy APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses., or user input), wrap it in a try/catch.
function safeJSONParse(jsonString, defaultValue = null) {
try {
return JSON.parse(jsonString);
} catch (error) {
console.error('Invalid JSON:', error);
return defaultValue;
}
}
const data = safeJSONParse(maybeJsonString, []);Quick reference
| Task | Method | Notes |
|---|---|---|
| Object to JSON string | JSON.stringify(obj) | Loses undefined, functions, Date |
| JSON string to object | JSON.parse(str) | Throws on invalid JSON |
| Parse API response | await response.json() | Shorthand for reading + parsing |
| Send object as body | body: JSON.stringify(obj) | Requires Content-Type: application/json |
| Safe nested access | obj?.a?.b?.c | Returns undefined instead of throwing |