Learning Goals
3 minBy the end of this lesson you will be able to:
- Turn a JSON string into a real object with
JSON.parse(). - Reach a value nested two levels deep, such as the temperature in KL.
- Replace the parse step with
response.json()in a fetch chain. - Spot the three rules that make JSON stricter than JavaScript.
Warm-Up · So Near, So Useless
5 minHere is the body you fetched last lesson, shortened. The temperature is clearly in there.
const body = '{"timezone":"GMT","current":{"temperature_2m":29.8}}';
console.log(body.current);
console.log(body.length);Predict together
- What does
body.currentgive you? - Why does
body.lengthwork whenbody.currentdoes not?
Reveal
undefined
51body is a string. Strings have a length, so that works. They do not have a current, so you get undefined.
The temperature is in there the way a word is in a sentence — as characters, not as a value you can reach. Today you convert it.
New Concept · A Shared Written Language
12 minTwo people who speak different languages can still share a recipe if they agree to write it in one agreed format. Computers have the same problem, and the same solution.
That format is JSON — JavaScript Object Notation. It looks like a JavaScript object, but it is only ever text. Every language can read it, which is why every API speaks it.
JSON is stricter than JavaScript
A JavaScript object
const dish = {
name: 'Nasi lemak',
price: 5.5,
spicy: true,
};Keys need no quotes. Single quotes fine. Trailing comma fine.
The same thing as JSON
{
"name": "Nasi lemak",
"price": 5.5,
"spicy": true
}Keys always in double quotes. Strings too. No trailing comma.
Three rules catch everybody out at least once:
- Double quotes only — on keys and on strings. Single quotes are invalid JSON.
- No trailing comma after the last item in an object or array.
- No comments, and no functions. JSON holds data, nothing else.
Allowed values are strings, numbers, true, false, null, arrays and objects. That is the whole list.
Text in, object out
const text = '{"name":"Roti canai","price":1.5}';
const dish = JSON.parse(text);
console.log(dish.price);1.5JSON.parse() reads the text and builds a real object. Now every trick from Lesson 11 works on it.
The reverse is JSON.stringify(), which turns an object back into text. You will need it in Level 3 when you send data to a server.
Reaching into nested data
Real API data is objects inside objects, and arrays inside those. You walk down with dots and square brackets — Lessons 9 and 11, unchanged.
{
"current": { "temperature_2m": 29.8 },
"hourly": {
"time": ["2026-08-08T00:00", "2026-08-08T01:00"],
"temperature_2m": [24.3, 26.2]
}
}const now = data.current.temperature_2m;
const firstHour = data.hourly.temperature_2m[0];
const firstTime = data.hourly.time[0];Notice how hourly works: two parallel arrays. Position 0 of one lines up with position 0 of the other. Many APIs do this.
The shortcut you will always use
Fetching and parsing go together so often that Response has a method for both.
fetch(url)
.then((response) => response.json())
.then((data) => {
console.log(data.current.temperature_2m);
});response.json() reads the body and parses it. It replaces .text() followed by JSON.parse(). From here on, use it.
Why it matters
Every API you meet for the rest of your life will hand you JSON. The moment it becomes an object, all your existing skills apply — and in React you will feed exactly this shape into a list on screen.
Worked Example · A Temperature, Not a Wall of Text
12 minCarry on in weather.html and app.js from last lesson. Run it with Live Server.
Step 1 — Parse it by hand, once
fetch(url)
.then((response) => response.text())
.then((body) => {
const data = JSON.parse(body);
console.log(data);
});Look in the console. Instead of a string you now get a foldable object with triangles to open. That is how you know it worked.
Step 2 — Reach the temperature
.then((body) => {
const data = JSON.parse(body);
const temperature = data.current.temperature_2m;
const unit = data.current_units.temperature_2m;
output.textContent = `${temperature} ${unit}`;
});29.8 °CThe units come from the API too, so the page stays correct even if the service changes them.
Step 3 — Drop the middle step
fetch(url)
.then((response) => response.json())
.then((data) => {
const temperature = data.current.temperature_2m;
const unit = data.current_units.temperature_2m;
output.textContent = `${temperature} ${unit}`;
});What changed? .text() became .json() and the JSON.parse line vanished. Same result, one step fewer.
Step 4 — Ask for the hourly forecast too
Add one more setting to the end of your URL:
const url = 'https://api.open-meteo.com/v1/forecast?latitude=3.14&longitude=101.69¤t=temperature_2m&hourly=temperature_2m';Reload and open data.hourly in the console. Two arrays, side by side, hundreds of entries long.
Step 5 — Show the first three hours
const times = data.hourly.time;
const temps = data.hourly.temperature_2m;
for (let i = 0; i < 3; i += 1) {
const li = document.createElement('li');
li.textContent = `${times[i]} — ${temps[i]} ${unit}`;
list.append(li);
}2026-08-08T00:00 — 24.3 °C
2026-08-08T01:00 — 26.2 °C
2026-08-08T02:00 — 29.2 °CAdd <ul id="list"></ul> to your HTML and select it first. The loop is Lesson 7 and createElement is Lesson 15 — the only new part is where the data came from.
One index, two arrays. That is the parallel-array idea doing real work.
Try It Yourself
13 minKeep building your weather page.
Task 1 — Say when
Show the reading time as well, from
data.current.time. Put it under the temperature in its own paragraph.Task 2 — Print it tidily
Log
JSON.stringify(data, null, 2)and compare it with plainJSON.stringify(data).The
2is how many spaces to indent by. Write one sentence on when each version is more useful.Task 3 — Six hours, and the warmest
Show the first six hours in your list instead of three. Then work out which of those six is warmest and mark it.
A loop with a “highest so far” variable will do it — Lesson 7 again. Keep the two arrays in step.
🔥 Mini-Challenge · The Menu That Will Not Parse
8 minHafiz wrote his stall menu as JSON by hand. Nothing appears, and the console is angry. Find three mistakes.
// hafiz-menu.js — buggy
const text = `{
'stall': 'Warung Hafiz',
'dishes': [
{ 'name': 'Nasi lemak', 'price': 5.5 },
{ 'name': 'Roti canai', 'price': 1.5 },
]
}`;
const menu = JSON.parse(text);
console.log(menu.dishes.price);It works if: the console logs 5.5 — the price of the first dish — with no error.
Reveal the answer
Mistake 1 — single quotes.
JSON allows double quotes only, on every key and every string. Single quotes are fine in JavaScript and invalid here. This alone stops JSON.parse dead:
SyntaxError: Expected property name or '}' in JSON at position 4The wording differs between browsers, but the position number is the gift — it tells you which character upset it.
Mistake 2 — a trailing comma.
There is a comma after the second dish with nothing following it. JavaScript forgives this; JSON never does.
Mistake 3 — reading an array as an object.
menu.dishes is an array, so it has no price — that gives undefined. Pick an item first with menu.dishes[0].price. This is the Lesson 9 index rule meeting the Lesson 11 dot.
// hafiz-menu.js — fixed
const text = `{
"stall": "Warung Hafiz",
"dishes": [
{ "name": "Nasi lemak", "price": 5.5 },
{ "name": "Roti canai", "price": 1.5 }
]
}`;
const menu = JSON.parse(text);
console.log(menu.dishes[0].price);In real work you rarely type JSON by hand — the API sends it. But when a parse fails, it is nearly always one of these three.
Note that a bad parse stops your code. Coping with that instead of crashing is Lesson 24.
Recap
3 min- JSON is text that looks like a JavaScript object. Every language reads it.
- Double quotes only · no trailing comma · no comments or functions.
JSON.parse(text)gives you a real object;JSON.stringify(obj)goes back.response.json()does the fetch-and-parse in one — use it instead of.text().- Walk into nested data with dots, and into arrays with
[0]. - Parallel arrays line up by index:
time[2]belongs withtemperature_2m[2]. - A value you cannot reach usually means you are one level too high or too low.
New words
- JSON — JavaScript Object Notation, the text format APIs speak.
- Parse — read text and build a real value from it.
- Stringify — the reverse: turn a value into text.
- Parallel arrays — two lists whose positions correspond.
Where this is going
You have now written .then() a dozen times without knowing what it really is. Next lesson opens it up: promises, their three states, and how to catch one that fails.
📦 Homework
4 min to brief · ~20 min to doRequired
- Write
menu.jsonfor a stall of your invention — the stall name, and an array of at least four dishes with a name and a price in RM. - Fetch it from your own page with Live Server, and render the dishes as a list showing
Nasi lemak — RM 5.50. Bring the JSON file and a screenshot of the rendered list.
Optional stretch
- Add a
spicyboolean to each dish and show a 🌶️ beside the spicy ones. Lesson 6'sifdoes the work. - Deliberately break your
menu.jsonwith a trailing comma. Read the error carefully and note what the position number points at.