Fetching Data with async and await
Until now the bakery's menu has been written into the HTML. The owner would rather update prices in one place and have the page load them fresh. The page can ask the server for the menu as data, using the same HTTP conversation from the first section, but from JavaScript. The catch: the answer takes time, and the page must not freeze while it waits.
The rule
fetchpromises a response: await it, checkok, then read the body.
async function loadMenu() {
try {
const response = await fetch("/api/menu");
if (!response.ok) {
throw new Error(`Menu request failed: ${response.status}`);
}
const items = await response.json();
showMenu(items);
} catch (error) {
showMessage("Sorry, the menu could not load. Please try again.");
}
}Promises. fetch does not return the response directly. It returns a promise, an object standing for a result that will arrive later. The rest of the page keeps working in the meantime: scrolling, clicking, animations.
await pauses this function only until the promise settles, then hands you the value. It can only be used inside a function marked async (or at the top level of a module). An async function always returns a promise itself.
Two awaits. The first await fetch(...) gives you the response once its status and headers arrive. The body may still be downloading, so reading it is another promise: await response.json() for JSON, or await response.text() for plain text.
Checking ok. Here is the surprise: fetch only rejects when the request could not be made at all, such as no network. A 404 or 500 is still a response, so the promise resolves normally. response.ok is true only for status codes from 200 to 299, so you must check it yourself.
Errors. Wrapping the work in try...catch catches both kinds of failure: a network error from fetch, and the error you throw for a bad status. Then you show the visitor a helpful message instead of a blank space.
The shortcut
Every fetch follows the same four beats: ask, await, check, read. Say them in order and you will not forget the check, which is the step beginners skip.
Ask
fetch("/api/menu")sends a GET request and returns a promise at once.
A related slip is forgetting await: const items = response.json(); stores a promise, not the menu, and items.length is undefined.
Drills
Answer fast — trust the rule.
The server replies 404 Not Found to a fetch. What happens to the promise?
Where can you use await?
What does const items = response.json(); without await store in items?
For which status is response.ok true?
Remember
fetchpromises a response: await it, checkok, then read the body.- Four beats: ask, await, check, read.
- Trap: 404 and 500 do not reject; forgetting
awaitleaves you holding a promise.
