6.7 — fetch & APIs
Everything async so far waited on timers. The real star of "later" is the network: your program asking another program — across the world — for data. The language for that conversation is HTTP, the data format is 4.13's JSON, and the JavaScript doorway is fetch.
One pattern to engrave — the two-await: first await the response head (status + headers), check it's ok, then await the body (res.json()). This exact dance is the foundation of API testing (Playwright's request fixture, lesson 11.8, is fetch in a test costume) — learn it here, use it for a decade.
async function loadPokemon() {
const res = await fetch(
"https://pokeapi.co/api/v2/pokemon/25"
);
console.log(res.status);
console.log(res.ok);
if (!res.ok) {
throw new Error("HTTP " + res.status);
}
const data = await res.json();
console.log(data.name);
}
loadPokemon();fetch(url) mails a REQUEST: an envelope carrying the method (GET — “give me”), the URL (which resource), and headers (metadata about the ask).
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
HTTP is textual and stateless: each request stands alone, carrying everything the server needs (that's why sessions need cookies/storage — lesson 7.7).
Beyond GET: POST sends data (a body on the request, plus options: fetch(url, { method: "POST", body: JSON.stringify(…) }) — the options object of 4.11!), PUT updates, DELETE removes. Same envelope dance, different verbs.
The two promises exist because bodies can be huge: the head arrives first and fast, so you can decide — is it ok? does its content-type header say "this is really JSON"? — before paying for the body. res.json() is the JSON body reader; res.text() exists for everything else.
The exercise uses a fake fetch deliberately. The sandbox has no network — and faking a response's shape is itself a professional skill. It is how tests mock APIs — Playwright's route.fulfill (lesson 11.10) is the same idea, built in. The shape you fake today is the shape you'll assert on for years.
⌨️ the two-await drill (offline edition)
The sandbox has no network — so build a faithful fake of fetch’s SHAPE and drill the exact pattern you’ll use on real APIs and in API tests: check the head, then parse the body.
requirements:
- A function
fakeFetch(url)that returns a Promise resolving to a response-shaped object:ok=true,status=200, and ajsonMETHOD that itself returns a Promise resolving to{ name: "pikachu", id: 25 }. - An async
main(): awaitfakeFetch("/pokemon/25"); if the response is not ok, thrownew Error("HTTP " + status); otherwise await.json(). - Print the data's
name, then itsid. Two awaits, one guard — the immortal pattern.
when you press RUN, the console must show exactly:
✏️ Quick check 1
A server replies 404. Does fetch’s promise reject? Type yes or no.
✏️ Quick check 2
Why TWO awaits? Because the first delivers the response ___ and the second delivers the ___. Type the two words (space-separated).
✏️ Quick check 3
Status 503 — whose side made the mistake? Type: client or server.
🗣️ Now teach it back
Walk a friend through what happens from fetch(url) to data.name — the envelopes, both awaits, the ok-guard, and why a 404 doesn’t reject the promise.
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.