‹ Build a Dashboard Lesson 8 of 16
Contents Lesson 8 of 16

4 min read · professional

Loading, empty, error — a cockpit's real states

One panel failing must not take down the page. That sentence is easy to agree with and requires specific work.

Per panel, not per page

A page-level spinner means the slowest panel decides when anything appears, and a page-level error means one bad symbol blanks the cockpit. Both are wrong for a surface with independent parts.

Each panel resolves its own state, and there are five, not two:

  • Loading — first fetch, no data yet. A skeleton the shape of the content, not a spinner.
  • Refreshing — has data, fetching newer. Keep showing the old data with a subtle marker. Blanking a panel to show a spinner over data you already have is the single most common dashboard mistake.
  • Ready — data, with its age.
  • Empty — the request succeeded and there is nothing. Say why: no symbols added, no rows matched.
  • Failed — say what failed and offer retry for that panel alone.

The distinction between loading and refreshing is where a cockpit feels calm or feels frantic, and it is one boolean.

Errors have kinds, and each needs different words

From what you have measured across three courses:

  • 404, plain text Ticker Not Found. — the person typed something wrong. Name the symbol. Course 3 met this one; note it is not JSON, so res.json() throws.
  • 429 — out of calls. This is the one people mislabel as "something went wrong", and it is the most important to get right because it is the wall arriving. Say "you are out of API calls for today" and show the meter.
  • 402 — the plan does not cover this data. Different from 429 and needs different words: more calls will not help.
  • 5xx or a timeout — upstream. Retry is reasonable here and only here.

Four kinds, four messages. A generic error message across all four is a tool that cannot tell you what to do next.

An error boundary per panel

Even with every state handled, a render bug in one panel should not blank the cockpit. Wrap each panel in a boundary that shows "this panel crashed" with a reset, and keep the rest of the page alive.

This matters more here than anywhere else in the track, because panels are the part you will keep adding. A cockpit where a new panel can take down the whole page is a cockpit you stop extending.

Degrade rather than disappear

When data is stale and cannot refresh, show it stale and label it. Do not hide it, and do not show it silently as if it were current.

That is the honest behaviour, and it is also the behaviour that makes the wall in unit 4 visible instead of confusing. A person who sees "AAPL 309.90 · 47 min old · refresh unavailable" understands their situation. A person who sees a blank panel thinks the tool is broken.

Try it now

Force all five states by hand: empty your watchlist, request a nonsense ticker, throttle the network, and throw inside a panel's render on purpose. Screenshot each. That set of five screenshots is the honest picture of your cockpit, and most dashboards have never had it taken.