Web APIs: Fetch, localStorage, Timers
Fetch API
// Basic GET request
fetch("https://api.example.com/users")
.then(res => {
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
return res.json();
})
.then(data => console.log(data))
.catch(err => console.error(err));
// With async/await
async function getUsers() {
const res = await fetch("https://api.example.com/users");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
}
// POST request
const createUser = async (userData) => {
const res = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer TOKEN"
},
body: JSON.stringify(userData)
});
return await res.json();
};
// PUT / PATCH / DELETE
await fetch(`/api/users/${id}`, { method: "DELETE" });
await fetch(`/api/users/${id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "New Name" })
});
// Response methods
response.json(); // parse JSON body
response.text(); // get as text
response.blob(); // get as Blob (files/images)
response.formData(); // get as FormData
response.status; // 200, 404, 500...
response.ok; // true for 200-299
response.headers.get("Content-Type");
localStorage and sessionStorage
// localStorage: persists across browser sessions
localStorage.setItem("token", "abc123");
localStorage.getItem("token"); // "abc123"
localStorage.removeItem("token");
localStorage.clear(); // remove all
localStorage.length; // number of items
// sessionStorage: cleared when tab/window closes
sessionStorage.setItem("cart", JSON.stringify([{id:1}]));
const cart = JSON.parse(sessionStorage.getItem("cart"));
// Both only store STRINGS — use JSON for objects
localStorage.setItem("user", JSON.stringify({ name: "Reet", role: "dev" }));
const user = JSON.parse(localStorage.getItem("user"));
// Utility wrapper
const storage = {
get: (key) => JSON.parse(localStorage.getItem(key)),
set: (key, value) => localStorage.setItem(key, JSON.stringify(value)),
remove: (key) => localStorage.removeItem(key)
};
Timers
// setTimeout: run ONCE after delay (milliseconds)
const timerId = setTimeout(() => {
console.log("Runs after 2 seconds");
}, 2000);
// Cancel before it fires
clearTimeout(timerId);
// setInterval: run REPEATEDLY at interval
const intervalId = setInterval(() => {
console.log("Runs every second");
}, 1000);
// Stop the interval
clearInterval(intervalId);
// Self-stopping interval
let count = 0;
const id = setInterval(() => {
console.log(count++);
if (count >= 5) clearInterval(id);
}, 1000);
// Promise-based delay
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
await sleep(2000); // pause 2 seconds in async function
// requestAnimationFrame (~60fps for smooth animations)
function animate(timestamp) {
element.style.left = (timestamp / 10 % 300) + "px";
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
URL and URLSearchParams
const url = new URL("https://example.com:3000/path?q=hello&page=2#section");
url.protocol; // "https:"
url.hostname; // "example.com"
url.port; // "3000"
url.pathname; // "/path"
url.search; // "?q=hello&page=2"
url.hash; // "#section"
url.searchParams.get("q"); // "hello"
url.searchParams.set("page", 3);
url.searchParams.append("sort", "asc");
url.toString(); // full URL with modifications
History API
history.pushState({ page: 2 }, "", "/page-2"); // add to history
history.replaceState({ page: 2 }, "", "/page-2"); // replace current
history.back(); // go back
history.forward(); // go forward
history.go(-2); // go back 2 pages
window.addEventListener("popstate", (e) => {
console.log(e.state);
});
Intersection Observer
// Detect when elements enter/exit the viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
observer.unobserve(entry.target); // stop observing
}
});
}, {
threshold: 0.1, // 10% visible to trigger
rootMargin: "0px 0px -100px 0px"
});
document.querySelectorAll(".lazy").forEach(el => observer.observe(el));
MCQ — Web APIs
Q1: When does response.ok return true?
A) Always B) Only for status 200 C) For status codes 200–299 ✅ D) For all non-error responses (200–399)
Answer: C
Q2: What is the difference between localStorage and sessionStorage?
A) localStorage is faster B) localStorage persists indefinitely; sessionStorage is cleared when the tab closes ✅ C) sessionStorage has more storage space D) localStorage stores objects, sessionStorage stores strings
Answer: B — Both store strings only and have similar 5-10MB limits.
Q3: Does fetch throw an error on a 404 response?
A) Yes, automatically
B) No — you must check response.ok or response.status manually ✅
C) Only in strict mode
D) Depends on the server
Answer: B — fetch only rejects on network failures, not HTTP errors like 404/500.
Q4: What does clearTimeout(id) do?
A) Clears all timeouts B) Cancels a specific pending timeout before it fires ✅ C) Resets the timeout timer D) Pauses the timeout
Answer: B
Q5: How do you store an object in localStorage?
A) localStorage.setItem("key", obj)
B) localStorage.setObject("key", obj)
C) localStorage.setItem("key", JSON.stringify(obj)) ✅
D) localStorage.set("key", obj)
Answer: C — localStorage only stores strings. Must serialize/deserialize with JSON.