AiTechWorlds
AiTechWorlds
University learning companion
Web Development Bootcamp 2026 · Fetch API & Async JavaScript
A feature looks correct on a developer’s large monitor but fails on a slow connection and a small screen. Use this topic to inspect structure, state, loading/error behaviour, accessibility and the user journey—not just the happy path.
Use this course-level map to place “Fetch API & Async JavaScript” in the larger system. It complements—not replaces—a topic-specific worked diagram.
Modern web apps load data from APIs without page reloads. The Fetch API combined with async/await is the standard way to do this cleaner than callbacks, more readable than raw Promises.
// fetch returns a Promise that resolves to a Response
const response = await fetch("https://api.example.com/users");
const users = await response.json(); // parse JSON body
// Always check response.ok — 404/500 don't reject the Promise!
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}// GET
const user = await fetch("/api/users/42").then(r => r.json());
// POST — send JSON
const newUser = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Alice", email: "alice@example.com" })
}).then(r => r.json());
// PUT — update
await fetch(`/api/users/42`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Alice B" })
});
// DELETE
await fetch(`/api/users/42`, { method: "DELETE" });async function apiFetch(url, options = {}) {
const response = await fetch(url, {
headers: { "Content-Type": "application/json" },
...options
});
if (!response.ok) {
const err = await response.json().catch(() => ({ message: response.statusText }));
throw Object.assign(new Error(err.message), { status: response.status });
}
if (response.status === 204) return null;
return response.json();
}
// Usage
try {
const users = await apiFetch("/api/users");
renderUsers(users);
} catch (err) {
if (err.status === 401) redirectToLogin();
else showErrorBanner(err.message);
}async function loadData(url, containerEl) {
// Show loading
containerEl.innerHTML = `<div class="spinner"></div>`;
containerEl.setAttribute("aria-busy", "true");
try {
const data = await apiFetch(url);
containerEl.innerHTML = renderContent(data);
} catch (err) {
containerEl.innerHTML = `
<div class="error">
<p>${err.message}</p>
<button onclick="loadData('${url}', this.closest('.container'))">
Try Again
</button>
</div>
`;
} finally {
containerEl.removeAttribute("aria-busy");
}
}// Sequential — slow (waits for each one)
const user = await apiFetch(`/api/users/${id}`);
const posts = await apiFetch(`/api/users/${id}/posts`);
const followers = await apiFetch(`/api/users/${id}/followers`);
// Total time = time1 + time2 + time3
// Parallel — fast (all at once)
const [user, posts, followers] = await Promise.all([
apiFetch(`/api/users/${id}`),
apiFetch(`/api/users/${id}/posts`),
apiFetch(`/api/users/${id}/followers`)
]);
// Total time = max(time1, time2, time3)// Cancel previous request when user types (search input)
let searchController = null;
async function search(query) {
// Cancel any ongoing search
searchController?.abort();
searchController = new AbortController();
try {
const results = await apiFetch(
`/api/search?q=${encodeURIComponent(query)}`,
{ signal: searchController.signal }
);
renderResults(results);
} catch (err) {
if (err.name === "AbortError") return; // expected, ignore
showError(err.message);
}
}
searchInput.addEventListener("input", debounce(e => search(e.target.value), 300));async function initComments(postId) {
const container = document.querySelector(".comments");
const form = document.querySelector("#comment-form");
// Load comments
await loadData(`/api/posts/${postId}/comments`, container);
// Add comment
form.addEventListener("submit", async (e) => {
e.preventDefault();
const text = form.querySelector("textarea").value.trim();
if (!text) return;
const submitBtn = form.querySelector("[type='submit']");
submitBtn.disabled = true;
submitBtn.textContent = "Posting...";
try {
const comment = await apiFetch(`/api/posts/${postId}/comments`, {
method: "POST",
body: JSON.stringify({ text })
});
form.reset();
// Prepend new comment to list
container.insertAdjacentHTML("afterbegin", renderComment(comment));
} catch (err) {
alert("Failed to post comment: " + err.message);
} finally {
submitBtn.disabled = false;
submitBtn.textContent = "Post Comment";
}
});
}Next lesson: Why React? JSX & Component Thinking the foundation of modern UI development.
University learning companion
Web Development Bootcamp 2026 · Fetch API & Async JavaScript
Complete the steps without looking at the answer first; record evidence rather than only a final result.
These are primary or established learning references for this subject. Check the relevant chapter or specification for the exact topic and version.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises