Free course · Lesson 4 of 5
Modern JavaScript: Fetching Data with async/await
In this lesson you will
- Load data with fetch and async/await
- Show loading and error messages
Real websites rarely keep all their content inside the HTML. Prices, timetables, news and products usually come from a server as JSON — plain text that looks like JavaScript objects and lists. Your page asks for the data, waits for it, and then builds the list or table with JavaScript. Headless content management systems and most web APIs deliver content in exactly this way.
- Arrow functions (
(s) => s.course) and template literals (`${s.day} at ${s.time}`) keep display code short and readable. - Fetching data takes time, so it returns a Promise — a value that will arrive later.
- Inside an
asyncfunction,awaitpauses until the Promise settles, so the code reads top to bottom like ordinary steps. fetch(url)requests data; checkres.okbefore callingres.json(), because a "404 Not Found" still counts as a reply.- Wrap the work in
try/catch: show "Loading…" first and a clear message if it fails. On slow or expensive connections, keep responses small and never leave the user looking at an empty page.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Class Timetable - Rescue Academy</title> <style> body { font-family: system-ui, sans-serif; padding: 2rem; background: #f0f4f8; } h1 { color: #1D448A; } li { background: white; padding: 0.75rem 1rem; margin-bottom: 0.5rem; border-radius: 8px; list-style: none; } .status { color: #555; } .error { color: #b91c1c; } </style></head><body> <h1>This Week's Classes</h1> <p id="status" class="status"></p> <ul id="sessions"></ul> <script> // Simulates a web API: the data arrives after a short delay. // A real site would call fetch() instead (see the comment below). function getSessions() { const data = [ { course: "Web Development", day: "Monday", time: "16:00" }, { course: "Graphic Design", day: "Wednesday", time: "10:00" }, { course: "Cybersecurity", day: "Friday", time: "14:00" } ]; return new Promise((resolve) => setTimeout(() => resolve(data), 800)); } // With a real API the function body would be: // const res = await fetch("https://example.com/api/sessions.json"); // if (!res.ok) throw new Error(`Server replied ${res.status}`); // return await res.json(); async function showSessions() { const status = document.getElementById("status"); const list = document.getElementById("sessions"); status.textContent = "Loading…"; try { const sessions = await getSessions(); list.innerHTML = sessions .map((s) => `<li><strong>${s.course}</strong> — ${s.day} at ${s.time}</li>`) .join(""); status.textContent = `${sessions.length} classes this week`; } catch (err) { status.textContent = "Could not load the timetable. Check your connection and try again."; status.className = "error"; } } showSessions(); </script></body></html>
Practice exercise
Load a list of events from a JSON file and display them, showing 'Loading…' first and a friendly message if the file cannot be loaded.
Key takeaways
- fetch returns a promise; await waits for it
- Check response.ok — fetch does not fail on 404
- Always plan for slow and failed requests
Free self-study lesson — no certificate. For the full instructor-led program, see registration options.