Thirty minutes from now you will have built
a working game out of data you never typed.
I'll do it, we'll do it, then you do it — same game, three
passes.
Thirty minutes, one game, three passes
Tonight
5 minFour words, then we look at real data in Postman — no code yet
6 minI do — one Pokémon on the page. You watch.
8 minWe do — a random mystery silhouette, together
9 minYou do — four guess buttons and a score. Now it's a game.
2 minHomework, and what changes when React shows up
No servers, no npm, no logins, no accounts.
A browser, VS Code, and Postman.
What you actually have to learn
3
lines of JavaScript. Not three files, not three frameworks.
Three lines — and they are the
same three lines in every file tonight.
Everything else is decoration.
An API is a URL that gives you data instead of a page
Four words
API
A computer that hands out data when you ask. Tonight: pokeapi.co
Endpoint
One specific URL on it. /pokemon/25 gives one, /pokemon?limit=151 gives a list
JSON
How data is written down while it travels. Looks like JavaScript, because it is
Status code
200 worked · 404 no such thing · 500 their fault
REST, HTTP verbs, headers, auth tokens, rate limits —
all of it can wait. People quit this subject because
somebody handed them forty words on night one.
Reading JSON · one question answers half of tonight's bugs
Brackets mean you can
loop it, count it, and pick from it at random. That one sentence is why a game is
possible tonight.
Three passes, three rules
I do → We do → You do
1During I do, hands off keyboards. Typing along means debugging instead of watching
2Read the red text. F12 → Console. An error is the computer telling you what's wrong — information, never a verdict on you
3Say STUCK the moment you're stuck. Stuck is a group problem here, never a private one
Three passes at the same game: I show you one
Pokémon, we hide a random one together, then you make it playable.
I do · 1 of 2 — just watch, you'll type in six minutes
I look at the data before I write code
Postman. New → HTTP Request. Method stays GET. I TYPE the URL:
https://pokeapi.co/api/v2/pokemon/25
I press Send. THE SCREEN SAYS:
Status: 200 OK
{ "id": 25, "name": "pikachu", "height": 4, "weight": 60,
"sprites": { "front_default": "https://.../sprites/pokemon/25.png" } }
Now I break it on purpose — I TYPE:
https://pokeapi.co/api/v2/pokemon/99999
Status: 404 Not Found
I say:
"Zero code so far — Postman means I'm never debugging my typing and guessing the data's shape
at the same time. And that 404? There is no Pokémon 99999, and the API said so clearly. Meet a
404 here, with me, not alone at 11pm when it feels like proof you can't do this."
I do · 2 of 2 — the whole tutorial, right here
I put one Pokémon on the page
js/step-1.js — at EDIT 2, I TYPE:
const response = await fetch(API_URL); // 1. ASK
const pokemon = await response.json(); // 2. UNWRAP
output.textContent = pokemon.name; // 3. SHOW
sprite.src = pokemon.sprites.front_default; // the picture is just a field!async = "there's a wait inside this function." Goes before function.await = "pause here until the data arrives." Goes before fetch and .json().
I say:
"Ask, unwrap, show. Two steps because response is a sealed envelope —
the status is printed on the outside, .json() opens it.
Next slide: let's run it."
I do · running for real, right here in the deck
Watch it worklive
Nothing yet. Click the button.
↑ a real fetch to pokeapi.co — the exact code on the slide before
We do · together, keyboards up — nobody types ahead
A random mystery
js/step-2.js. New URL — a LIST this time. YOU TYPE:
const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=151");
const data = await response.json();
allPokemon = data.results; // 151 of them, in [ ]Pick one nobody chose — that's a mystery:
mystery = allPokemon[Math.floor(Math.random() * allPokemon.length)];
Build the picture address from its number, then hide it:
const id = mystery.url.split("/")[6]; // ".../pokemon/25/" → "25"
sprite.src = SPRITE_BASE + id + ".png";
sprite.classList.add("hidden"); // CSS: filter: brightness(0)
Checkpoint: a black silhouette, and Reveal shows who it
is. Thumbs up.brightness(0) paints every pixel black
— the whole effect, one line of CSS.
We do · running for real
The mysterylive
↑ one fetch of 151 names · a random pick · one CSS class on and off
You do · nine minutes · now make it playable
Make it a game*
A mystery you can only
look at isn't a game. Add
four buttons and a score and it is.
1Write the two fetch lines — third time tonight, you've got this
2Loop the four choices into four buttons (same forEach shape as always)
3Right or wrong? Add to the score and colour the button
step-3-you-do.html
You do · this is what you're building — play it
The gamelive
SCORE 0 / 0
↑ the finished thing in game.html · press 1-4 to guess, Enter for the next round
Where it goes · game.html, already in your folder
The finished game needs four more things
Loads on open
No "click me" button. Real sites just load.
Keeps score
Score, streak, personal best — and keys 1–4 to play fast.
Loading message
They wait 200 milliseconds. Say something.
Error message
Wifi dies, API goes down. Never show a blank page.
Built and commented in game.html + js/game.js —
three files, split the way real sites split them. The shape to steal:
change state, then call
render(). Never edit the page directly. That is exactly the
habit React requires, so practising it tonight is free.
Two minutes · what's coming, and what to watch
React changes less than you think
What you wrote tonight
In React
Changes?
choices.forEach(...)
choices.map(c => <Choice />)
Same loop
Calling render() yourself
React does it for you
you delete it
fetch / await / .json()
identical
nothing
class="ics-choice"
className="ics-choice"
One word
Homework — Pluralsight, pick ONE
and finish it.React Fundamentals (or the React 18 path) if you're ready ·
JavaScript: Getting Started if JS still feels shaky ·
JavaScript Promises and Async Programming if await bugged you ·
Guided: APIs in JavaScript if you learn by doing. Links in the README.
Screenshot this before you go
When it breaks
The screen says
The fix
Promise { <pending> }
You forgot await — it goes before fetch AND before .json()
Cannot read properties of undefined
Wrong field name, or a level of nesting skipped. Is it sprites.front_default?
await is only valid in async functions
Add async before the word function
A broken-image icon
The sprite URL is wrong — check the id you pulled out of the url
Nothing happens on click
id must match getElementById exactly — case-sensitive
In thirty minutes you asked another computer for data,
put it on your own page, and turned it into a game somebody would actually play.
Ask, unwrap, show.