i.c.stars|*Milwaukee
RFP Tech Learning · Week 6
1 / 16
→ arrow keys or tap sides
Tonight · 30 minutes · guided tutorial

Hello,
API*

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

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

Braces or brackets?

CURLY BRACES = one thing. /pokemon/25 gives you: { "id": 25, "name": "pikachu", "weight": 60, "sprites": { "front_default": "https://.../25.png" } } ↑ NESTED. A dot means "go inside": pokemon.sprites.front_default SQUARE BRACKETS = a list. /pokemon?limit=151 gives you: { "results": [ { "name": "bulbasaur", "url": ".../pokemon/1/" }, { "name": "ivysaur", "url": ".../pokemon/2/" }, ...149 more ] }

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

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

Mystery Pokémon silhouette

↑ 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.

step-3-you-do.html

You do · this is what you're building — play it

The gamelive

Mystery Pokémon silhouette
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 tonightIn ReactChanges?
choices.forEach(...)choices.map(c => <Choice />)Same loop
Calling render() yourselfReact does it for youyou delete it
fetch / await / .json()identicalnothing
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 saysThe fix
Promise { <pending> }You forgot await — it goes before fetch AND before .json()
Cannot read properties of undefinedWrong field name, or a level of nesting skipped. Is it sprites.front_default?
await is only valid in async functionsAdd async before the word function
A broken-image iconThe sprite URL is wrong — check the id you pulled out of the url
Nothing happens on clickid 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.