Intermediate · JavaScript in depth · topic 34 of 64 · 35 min
JSON and working with real data
Explanation
What JSON is
JSON (JavaScript Object Notation) is a text format for data. Almost every web API sends and receives JSON. You met JSON.stringify and JSON.parse when saving to localStorage; here you learn the rules and how to handle bigger, real data.
{
"pnr": "4521367890",
"train": { "number": "12627", "name": "Karnataka Express" },
"passengers": [
{ "name": "Anil", "age": 45, "status": "CNF" },
{ "name": "Sunita", "age": 41, "status": "RAC" }
],
"chartPrepared": false,
"coach": null
}The rules
| Rule | Allowed in JSON | Not allowed |
|---|---|---|
| Keys and strings | "name": "Anil" | name: 'Anil' (both need double quotes) |
| Values | strings, numbers, true, false, null, objects, arrays | undefined, functions, NaN, Infinity |
| Commas | [1, 2, 3] | [1, 2, 3,] (no comma after the last item) |
| Comments | None at all | // or /* */ |
JSON.stringify: data to text
const order = {
id: 'A101',
total: 499,
coupon: undefined, // dropped
print() {}, // dropped
placedAt: new Date('2026-03-15T10:30:00Z'),
};
JSON.stringify(order);
// '{"id":"A101","total":499,"placedAt":"2026-03-15T10:30:00.000Z"}'
JSON.stringify({ a: 1, b: [2, 3] }, null, 2); // pretty text with a 2-space indent
JSON.stringify([1, undefined, NaN]); // '[1,null,null]'undefined and functions are silently left out of objects, and become null inside arrays. NaN and Infinity become null. A Date becomes an ISO date string like "2026-03-15T10:30:00.000Z", so after JSON.parse it is a string, not a Date.
JSON.parse: text to data, safely
function safeParse(text, fallback) {
try {
return JSON.parse(text);
} catch {
return fallback; // broken or empty text
}
}
safeParse('{"ok":true}', {}); // { ok: true }
safeParse("{'ok': true}", {}); // {} single quotes are not JSON
safeParse('', []); // [] empty text is not JSON eitherReading deep values safely
const res = {
data: {
trains: [
{ number: '12627', name: 'Karnataka Express', classes: [{ code: '3A', seats: 12 }] },
{ number: '12951', name: 'Mumbai Rajdhani', classes: [] },
],
},
};
res.data.trains[0].name; // 'Karnataka Express'
res.data?.trains?.[5]?.name; // undefined, no crash
res.data.trains[1].classes[0]?.seats ?? 0; // 0 (no classes listed)
res.meta?.page ?? 1; // 1 (default when missing)Use ?.[ ] for an index that may not exist and ?.( ) for a function that may not exist. Together with ??, they turn "Cannot read properties of undefined" crashes into sensible defaults.
Shaping data for the page
function toCards(res) {
return (res.data?.trains ?? []).map((t) => ({
title: `${t.number} ${t.name}`,
seats: t.classes.reduce((sum, c) => sum + c.seats, 0),
}));
}
toCards(res);
// [{ title: '12627 Karnataka Express', seats: 12 },
// { title: '12951 Mumbai Rajdhani', seats: 0 }]Deep copies and dates
const original = { id: 'A1', items: [{ name: 'rice', qty: 1 }] };
const copy = structuredClone(original);
copy.items[0].qty = 5;
console.log(original.items[0].qty); // 1 the original is safe
const d = new Date('2026-08-15');
d.getFullYear(); // 2026
d.toISOString(); // '2026-08-15T00:00:00.000Z'
const back = JSON.parse(JSON.stringify({ when: d }));
typeof back.when; // 'string'
new Date(back.when).getFullYear(); // 2026 turned back into a DatestructuredClone copies every level, unlike spread, and keeps Dates as Dates. It cannot copy functions. The old trick JSON.parse(JSON.stringify(x)) also makes a deep copy, but it loses undefined, functions and real Dates, so prefer structuredClone.
Watch the lesson
JSON and working with real data · 1/7
JSON is text that carries data between servers and apps.
Prefer a video by a teacher? Find free videos on “javascript JSON parse stringify optional chaining nested data tutorial” on YouTube ↗
In real life: A PNR status page
A train enquiry site asks the server for your PNR status and gets JSON back. The page parses it inside try/catch, reads data?.passengers ?? [] so a half-empty reply does not crash the page, turns each passenger into a small { name, status } object for the list, and converts the "chartPreparedAt" string back into a Date to show the time the chart was prepared.
Practice (0/3 done)
Write a function safeParse(text, fallback) that returns JSON.parse(text), or returns fallback when the text is not valid JSON. Example: safeParse('{"ok":true}', null) returns { ok: true }, and safeParse("{ok: true}", null) returns null.
An API returns train data shaped like { data: { trains: [ { number, name, classes: [ { code, seats } ] } ] } }. Write a function trainCards(res) that returns an array of { title, seats }. title is the number and name joined by a space, like "12627 Karnataka Express". seats is the total of seats over all classes. If res, data or trains is missing, return []. If a train has no classes array, its seats are 0.
Write the JSON for one grocery order by hand: an order id, a customer object (name and PIN code), an items array (name, qty, price for each) and a delivered flag. Paste it into the DevTools Console inside JSON.parse('...') and check it parses. Then read the first item's name with ?. and the coupon (which does not exist) with ?? "NONE".
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.