Fetch API & Working with JSON
পাঁচ লাইনে যেকোনো HTTP API-তে কথা বলুন
1. Basic fetch
fetch(url) returns a Promise that resolves to a Response object. Call .json() (or .text(), .blob()) on it to read the body — also a Promise.
// Real browser code
const res = await fetch("https://jsonplaceholder.typicode.com/users/1");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const user = await res.json();
console.log(user.name);
fetch built-in। আগে XMLHttpRequest লাগত। res.ok চেক না করলে 404/500-ও silently পেরিয়ে যায় — ফalse করেও Promise reject হয় না।2. Status & Errors — A Common Trap
fetch only rejects on network failures. A 404 or 500 still resolves with a Response — you must check res.ok yourself.
// Sandbox-runnable simulation
function fakeFetch(url) {
const map = {
"/ok": { ok: true, status: 200, body: { msg: "hello" } },
"/notfound": { ok: false, status: 404, body: { error: "missing" } },
};
const r = map[url];
if (!r) return Promise.reject(new Error("network"));
return Promise.resolve({
ok: r.ok, status: r.status,
json: () => Promise.resolve(r.body)
});
}
(async () => {
for (const url of ["/ok", "/notfound"]) {
const r = await fakeFetch(url);
if (!r.ok) {
console.log("http err:", r.status);
continue;
}
console.log("data:", await r.json());
}
})();
3. POST with JSON Body
const res = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify({ name: "Arif", age: 22 })
});
const created = await res.json();
4. URLSearchParams & Query Strings
const qs = new URLSearchParams({ q: "javascript bangla", page: 2 });
console.log(qs.toString()); // q=javascript+bangla&page=2
console.log(`/search?${qs}`);
const url = new URL("https://abcl.tech/search");
url.searchParams.set("q", "hi");
console.log(url.toString());
5. AbortController — Cancel a Request
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 3000); // 3-sec ceiling
try {
const res = await fetch("/slow", { signal: ctrl.signal });
const data = await res.json();
console.log(data);
} catch (e) {
if (e.name === "AbortError") console.log("cancelled");
else throw e;
} finally {
clearTimeout(t);
}
6. CORS in Two Sentences
Access-Control-Allow-Origin: .... Anything other than simple GET/HEAD/POST may also trigger a "preflight" OPTIONS request. CORS is a server-side configuration — there's nothing your JS can do to bypass it.
7. JSON.parse & JSON.stringify
const obj = { name: "Arif", age: 22, hobbies: ["chess", "reading"] };
// stringify with indent
const json = JSON.stringify(obj, null, 2);
console.log(json);
// stringify with replacer (filter keys)
console.log(JSON.stringify(obj, ["name", "age"]));
// parse + reviver — transform values during parse
const rev = JSON.parse('{"a":"hi","b":42}', (k, v) =>
typeof v === "string" ? v.toUpperCase() : v);
console.log(rev);
undefined, no functions, no Date, no BigInt. They get dropped or coerced. NaN and Infinity become null.
8. Glossary (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
fetch | Browser/Node API to make HTTP requests. | HTTP request-এর জন্য আধুনিক API। |
Response | The object fetch resolves with — has status, headers, body. | fetch-এর resolved object — status/headers/body থাকে। |
res.ok | True for HTTP status 200-299 — must check manually. | 2xx status হলে true — নিজে চেক করতে হয়। |
JSON | JS-subset text format for data exchange. | JS-এর subset text format — data বিনিময়ের জন্য। |
JSON.parse | Convert JSON text to a JS value. | JSON string থেকে JS value বানায়। |
JSON.stringify | Convert a JS value to JSON text. | JS value থেকে JSON string বানায়। |
URLSearchParams | Helper to build/read query strings safely. | Query string সঠিকভাবে তৈরি/পড়ার tool। |
AbortController | Lets you cancel an in-flight fetch. | চলমান fetch-কে cancel করার tool। |
| CORS | Cross-Origin Resource Sharing — browser opt-in for cross-site reads. | Browser-এর cross-origin opt-in protocol। |
fetch network failure ছাড়া reject হয় না — 404/500-ও Response হিসেবে আসে। তাই res.ok চেক করতেই হবে। JSON-এ Date/Map/BigInt নেই — replacer/reviver দিয়ে সামলান। CORS server-side configuration; JS দিয়ে bypass করা যায় না — third-party API হলে নিজের server-এ proxy করুন।
9. Practice Problems
- Stringify an object with 2-space indent.
✨ Show Answer
a1.jsconsole.log(JSON.stringify({ a: 1, b: [2, 3] }, null, 2)); - Parse a JSON string into an object.
✨ Show Answer
a2.jsconst obj = JSON.parse('{"name":"Arif","age":22}'); console.log(obj.name, obj.age); - Show that
JSON.stringify(undefined)is the stringundefined… not valid JSON.✨ Show Answer
a3.jsconsole.log(JSON.stringify(undefined)); // undefined (the JS value, not the string) console.log(JSON.stringify({ a: undefined })); // "{}" console.log(JSON.stringify([undefined])); // "[null]" - Build a fetch wrapper
getJSON(url)that throws on non-2xx.✨ Show Answer
async function getJSON(url, opts) { const res = await fetch(url, opts); if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); } - Build a query string for {q:"hi", page:2}.
✨ Show Answer
a5.jsconst qs = new URLSearchParams({ q: "hi", page: 2 }).toString(); console.log(qs); - Demonstrate that fetch on 404 still resolves.
✨ Show Answer
Conceptually:
const res = await fetch("/missing"); console.log(res.ok, res.status); // false 404fetch only rejects on network failures (DNS error, offline, CORS); HTTP errors are normal Responses.
- Show how to attach
Authorizationand JSON Content-Type headers.✨ Show Answer
fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${token}` }, body: JSON.stringify(data) }); - Use
JSON.stringifywith a replacer function to drop secrets.✨ Show Answer
a8.jsconst hide = (k, v) => (k === "password" ? undefined : v); console.log(JSON.stringify({ name: "a", password: "x" }, hide)); - Use
JSON.parsewith a reviver to convert ISO date strings to Date objects.✨ Show Answer
a9.jsconst isISO = s => typeof s === "string" && /^\d{4}-\d\d-\d\dT/.test(s); const revive = (k, v) => isISO(v) ? new Date(v) : v; const j = '{"created":"2026-05-09T10:00:00Z"}'; console.log(JSON.parse(j, revive)); - Use AbortController to cancel a slow fetch (sketch).
✨ Show Answer
const ctrl = new AbortController(); setTimeout(() => ctrl.abort(), 3000); fetch("/slow", { signal: ctrl.signal }) .catch(e => e.name === "AbortError" && console.log("cancelled")); - Why is JSON not enough to serialise
Date,Map,BigInt?✨ Show Answer
Answer: JSON is a JS-subset format with only the six basic types (object, array, string, number, boolean, null). Dates serialise as ISO strings (one-way), Map and Set serialise as
{}, BigInt throws. Use replacer/reviver to convert manually, or pick a richer format likestructuredClonefor in-memory work. - Construct a URL with
new URLand add query params.✨ Show Answer
a12.jsconst u = new URL("https://abcl.tech/search"); u.searchParams.set("q", "javascript bangla"); u.searchParams.set("page", 2); console.log(u.toString()); - Build a fetch+timeout helper using Promise.race.
✨ Show Answer
a13.jsconst withTimeout = (p, ms) => Promise.race([ p, new Promise((_, r) => setTimeout(() => r(new Error("timeout")), ms)) ]); withTimeout(new Promise(r => setTimeout(() => r("slow"), 100)), 30) .catch(e => console.log(e.message)); - In one paragraph, what is CORS and why can't your JS bypass it?
✨ Show Answer
Answer: CORS is the browser's same-origin protection: scripts can read responses from a different origin only if that origin opts in via
Access-Control-Allow-Origin. The browser enforces this in C++ before your JS sees the response, so no fetch options or polyfill can override it. To talk to a third-party API that doesn't enable CORS, route the call through your own server.
Summary — Module 24
fetch + res.json() is the modern way to talk to HTTP APIs. Always check res.ok; fetch never rejects on 404/500. Set headers and JSON body for POST. Cancel with AbortController. CORS is server-controlled. JSON is a tiny subset of JS — beware Dates, Maps, and BigInt.
res.ok চেক করুন। CORS server-side configuration — JS দিয়ে bypass করা যায় না।