Fetch API (Modern AJAX)

লেসন ৪০ / ৪৪

Fetch API — আধুনিক AJAX

fetch() হলো আধুনিক browser-এর built-in ফাংশন যা Promise return করে। XHR-এর চেয়ে অনেক সহজ।

Basic GET Request

fetch("https://jsonplaceholder.typicode.com/users")
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error("Error:", error));

async/await দিয়ে (সবচেয়ে পরিষ্কার) ⭐

async function getUsers() {
    try {
        const response = await fetch("https://jsonplaceholder.typicode.com/users");

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }

        const users = await response.json();
        console.log(users);
        return users;
    } catch (error) {
        console.error("ভুল:", error);
    }
}

getUsers();

Response Object

const res = await fetch(url);

res.ok          // true যদি status 200-299
res.status      // 200, 404, 500...
res.statusText  // "OK", "Not Found"
res.headers     // Response headers

// Body parsing methods (Promise return করে)
await res.json()    // JSON → object
await res.text()    // টেক্সট
await res.blob()    // binary (image, file)
await res.formData()
await res.arrayBuffer()

POST Request (JSON পাঠানো)

async function createUser(userData) {
    const response = await fetch("https://api.example.com/users", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer YOUR_TOKEN"
        },
        body: JSON.stringify(userData)
    });

    const result = await response.json();
    return result;
}

createUser({ name: "করিম", age: 25 });

PUT / PATCH / DELETE

// UPDATE
await fetch("/api/users/1", {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name: "করিম উপডেটেড" })
});

// PATCH (আংশিক)
await fetch("/api/users/1", {
    method: "PATCH",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ age: 26 })
});

// DELETE
await fetch("/api/users/1", { method: "DELETE" });

File Upload (FormData)

const fileInput = document.querySelector("#file");
const formData = new FormData();
formData.append("avatar", fileInput.files[0]);
formData.append("userId", 42);

// Content-Type দেবেন না — browser নিজে সেট করবে!
await fetch("/api/upload", {
    method: "POST",
    body: formData
});

Query Parameters

const params = new URLSearchParams({
    q: "web design",
    page: 1,
    limit: 10
});

fetch(`/api/search?${params}`)
    .then(r => r.json())
    .then(data => console.log(data));

Request Cancel (AbortController)

const controller = new AbortController();

fetch(url, { signal: controller.signal })
    .then(r => r.json())
    .catch(err => {
        if (err.name === "AbortError") {
            console.log("Request cancelled");
        }
    });

// ৫ সেকেন্ড পরে cancel
setTimeout(() => controller.abort(), 5000);

একাধিক Request একসাথে

const [users, posts, comments] = await Promise.all([
    fetch("/api/users").then(r => r.json()),
    fetch("/api/posts").then(r => r.json()),
    fetch("/api/comments").then(r => r.json())
]);

বাস্তব উদাহরণ: Live Search

const searchBox = document.querySelector("#search");
let timer;

searchBox.addEventListener("input", (e) => {
    clearTimeout(timer);
    timer = setTimeout(async () => {
        const query = e.target.value.trim();
        if (!query) return;

        const res = await fetch(`/api/search?q=${query}`);
        const results = await res.json();
        renderResults(results);
    }, 300);  // debounce
});