Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
The Client Half  ›  Lesson

Click, Fetch, Update

Checkpoint - Interactivity 13 minEvery interaction with a server has four beats: listen for the event, send the request with fetch, check the response status because fetch does not fail on error codes, and update the page from the server's answer.

Click, Fetch, Update

Sprout's "Add plant" form looks simple. Behind it, the browser must notice the submit, send the plant to the server, wait, check the answer, and only then change what the user sees. Skip the checking step and the screen can cheerfully show a plant that was never saved.

The rule

Listen, send, check, update.

Every interaction that talks to a server has these four beats:

form.addEventListener('submit', async (event) => {
  event.preventDefault();                                  // listen

  const res = await fetch('/api/plants', {                 // send
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name: nameInput.value, water_every_days: Number(daysInput.value) }),
  });

  if (!res.ok) {                                           // check
    message.textContent = `Could not save (error ${res.status}).`;
    return;
  }

  const plant = await res.json();                          // update
  list.append(renderPlant(plant));
});
  • Listen. The handler runs on submit. event.preventDefault() stops the browser's old-style form submission, which would reload the whole page.
  • Send. fetch takes a method, headers and a body. JSON.stringify turns the object into text, and Content-Type: application/json tells the server how to read it.
  • Check. fetch only fails outright when no response arrives at all, such as when the network is down. A 400 or 500 still counts as a response, so you must look at res.ok, which is true only for statuses from 200 to 299. (A real app also wraps the call in try/catch to handle the network failing.)
  • Update. Change the page using the server's version of the plant. It carries the id the database just assigned, which later edits and deletes need.

One more guard is worth the two lines it costs: disable the Add button when the request leaves and enable it again when the answer arrives. Otherwise an impatient double-click sends two POSTs, and Asha ends up with two identical Basils.

The shortcut

Read any interaction code and name its four beats. A missing beat is the bug. No check: failures are silent. Update before send with no way back: the screen can lie. No preventDefault: the page reloads and your code is cut off.

Tracing "Add plant"Step 1 of 4
  1. Listen

    Asha types "Basil" and 2, and presses Add. The submit handler runs, and preventDefault keeps the page in place.

Drills

Answer fast — trust the rule.

quick drill

The server answers 500. What does fetch do?

quick drill

The submit handler forgets event.preventDefault(). What happens?

quick drill

Why build the new list item from the response rather than from the typed values?

quick drill

Which header tells Sprout's server that the request body is JSON?

Remember

  • Listen, send, check, update.
  • Shortcut: name the four beats in any handler; a missing beat is the bug.
  • Trap: trusting fetch to fail on errors. It only fails when no response arrives, so always check res.ok.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainThe delete that removes too early

A delete handler removes the plant from the list, then calls fetch('/api/plants/7', { method: 'DELETE' }) and ignores the result. Using listen, send, check, update, explain what can go wrong and how you would reorder it.