Tutorial 1: Fetch, Promises, Modules, and State

Unit 3 · Advanced browser programming

Objectives

async function loadCourses() {
  const response = await fetch('/api/courses');
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
}

loadCourses().then(renderCourses).catch(showError);

Asynchronous code must represent its states explicitly. A view should not show stale data as if it were current, and errors should give users a recoverable next action. Modules should expose small public functions and keep implementation details private.

Exercises

  1. Render loading, empty, success, and error states for a JSON list.
  2. Add an AbortController timeout.
  3. Store a selected course id without duplicating server data.

Self-check

  1. Why check response.ok?
  2. What states should an asynchronous view represent?
  3. Why separate modules?

Self-Check Quiz

1. Does fetch reject automatically for HTTP 404?

AnswerNo. It usually resolves with a response, so application code should check response.ok.

2. What does await response.json() return?

AnswerThe parsed body after the asynchronous JSON operation completes.

Homework

  1. Build a searchable course list backed by a JSON endpoint.
  2. Show loading and retryable error states.
  3. Explain how your modules prevent duplicated state.
Sample answerA strong solution has one data module responsible for fetching, one state owner for loading/error/data, and a view that renders each state. Retry starts a new request, and stale results are ignored or cancelled when a newer search begins.
👤