← Build · all briefsBrief 2 · after "Connect the market" · demo next class
Brief 2

Order board

Order from a stall without queueing: your name, a button, and a ticket that updates by itself from placed to preparing to ready. The server has no push: the page asks every two seconds, and stops when there's nothing left to ask. ★★☆

“I'll get the dumplings, you hold the table. They'll call my name, right?”

You'll demo (next class): order from Taco Bike as "Ana": a ticket appears and changes state twice on its own. When it's ready, the Network panel goes quiet. Order from Churros: the server says sold out, and the page says it better.

The core (start in class if you've connected, the minimum for the demo)

Four things, on top of your connected market. They count when they work with chaos on (control page).

The full feature (finish at home)

What has to work for the demo next class, not how. The core above is part of it.

Requests

  • An "Order" button on every card, and a name field (asked once, remembered in localStorage). The page doesn't decide what's orderable: the server does, with a 409.
  • POST /api/orders with { stallId, name }.
  • Poll GET /api/orders/:id every 2 s while the order isn't ready; then stop.

States

  • A list of my tickets: stall, name, status. Each status looks different; "ready" is impossible to miss.
  • My orders survive a reload: their ids in localStorage, their status from the server.
  • Ordering is disabled while the POST is in flight.

Errors

  • 409 sold_out: a sentence on that card, not an alert.
  • A failed poll doesn't kill the polling: the ticket says "reconnecting…" and the next tick tries again.
  • No two pollers for the same order, ever.

New tool: Repeating work: setInterval / clearInterval, or a setTimeout that schedules the next one after each response.

New tool: document.visibilityState: is anyone looking at this tab?

The endpoints you need

MethodPathAnswers
POST/api/orders201 { id, status: "placed", … } · 409 sold out · 422 { fields }
GET/api/orders/:id200 · status: placed → preparing (after 5 s) → ready (after 15 s) · 404
GET/api/orders200 · every order, newest first

Resetting your market (control page) forgets the orders, and the ids in your localStorage then answer 404. Handle it.

Edge cases (with chaos on, minutes 38–43)

Stretch, if you're done early

Stuck? One hint at a time

Network panel first: is the request sent, with what, and what came back? Then a hint.

Hint 1

setInterval or a chain of setTimeouts: which one can start a new request before the previous one answered?

Hint 2

Where do you keep the timer ids, so the code that sees "ready" can stop the right one?

Hint 3

After a reload, the ids are in localStorage. What's the first request for each of them?

Traps

Open when something behaves strangely

Before you start

This brief assumes Connect the market is done: api.js works, the stalls come from the API, loading and errors are handled. Then: An Order button sends POST /api/orders: 201 in the Network panel, and the order's id in the console.

Demo · next class, 3 minutes

Your 3 minutes
  1. The happy path, with the Network panel open next to the page.
  2. Chaos on: the loading state, one failure, and how the page recovers.
  3. One request in code: the call, the status codes you handle, where the state changes.
  4. One bug you hit, and the panel or the message that showed it to you.