Fetch API & Working with JSON

পাঁচ লাইনে যেকোনো HTTP API-তে কথা বলুন

~35 min Intermediate 14 practice problems Live runner

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);
Modern browser-এ 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.

status.js
// 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

qs.js
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

Browsers block cross-origin requests by default. The server must opt in by sending 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

json.js
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);
JSON gotchas JSON has no undefined, no functions, no Date, no BigInt. They get dropped or coerced. NaN and Infinity become null.

8. Glossary (শব্দকোষ)

TermMeaningবাংলায়
fetchBrowser/Node API to make HTTP requests.HTTP request-এর জন্য আধুনিক API।
ResponseThe object fetch resolves with — has status, headers, body.fetch-এর resolved object — status/headers/body থাকে।
res.okTrue for HTTP status 200-299 — must check manually.2xx status হলে true — নিজে চেক করতে হয়।
JSONJS-subset text format for data exchange.JS-এর subset text format — data বিনিময়ের জন্য।
JSON.parseConvert JSON text to a JS value.JSON string থেকে JS value বানায়।
JSON.stringifyConvert a JS value to JSON text.JS value থেকে JSON string বানায়।
URLSearchParamsHelper to build/read query strings safely.Query string সঠিকভাবে তৈরি/পড়ার tool।
AbortControllerLets you cancel an in-flight fetch.চলমান fetch-কে cancel করার tool।
CORSCross-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

  1. Stringify an object with 2-space indent.
    ✨ Show Answer
    a1.js
    console.log(JSON.stringify({ a: 1, b: [2, 3] }, null, 2));
  2. Parse a JSON string into an object.
    ✨ Show Answer
    a2.js
    const obj = JSON.parse('{"name":"Arif","age":22}');
    console.log(obj.name, obj.age);
  3. Show that JSON.stringify(undefined) is the string undefined… not valid JSON.
    ✨ Show Answer
    a3.js
    console.log(JSON.stringify(undefined));     // undefined (the JS value, not the string)
    console.log(JSON.stringify({ a: undefined })); // "{}"
    console.log(JSON.stringify([undefined]));      // "[null]"
  4. 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();
    }
  5. Build a query string for {q:"hi", page:2}.
    ✨ Show Answer
    a5.js
    const qs = new URLSearchParams({ q: "hi", page: 2 }).toString();
    console.log(qs);
  6. Demonstrate that fetch on 404 still resolves.
    ✨ Show Answer

    Conceptually:

    const res = await fetch("/missing");
    console.log(res.ok, res.status);   // false 404

    fetch only rejects on network failures (DNS error, offline, CORS); HTTP errors are normal Responses.

  7. Show how to attach Authorization and JSON Content-Type headers.
    ✨ Show Answer
    fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${token}`
        },
        body: JSON.stringify(data)
    });
  8. Use JSON.stringify with a replacer function to drop secrets.
    ✨ Show Answer
    a8.js
    const hide = (k, v) => (k === "password" ? undefined : v);
    console.log(JSON.stringify({ name: "a", password: "x" }, hide));
  9. Use JSON.parse with a reviver to convert ISO date strings to Date objects.
    ✨ Show Answer
    a9.js
    const 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));
  10. 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"));
  11. 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 like structuredClone for in-memory work.

  12. Construct a URL with new URL and add query params.
    ✨ Show Answer
    a12.js
    const u = new URL("https://abcl.tech/search");
    u.searchParams.set("q", "javascript bangla");
    u.searchParams.set("page", 2);
    console.log(u.toString());
  13. Build a fetch+timeout helper using Promise.race.
    ✨ Show Answer
    a13.js
    const 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));
  14. 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.

fetch + res.json() — মূল প্যাটার্ন। res.ok চেক করুন। CORS server-side configuration — JS দিয়ে bypass করা যায় না।

Next Module → The DOM — gardenভাবে edit করুন।