GET Request

// Basic GET
const res = await fetch('https://api.example.com/users');
const data = await res.json();
console.log(data);

// With error handling
async function getUsers() {
  try {
    const res = await fetch('https://api.example.com/users');
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('Fetch failed:', err);
  }
}
⚠️ Important: fetch() only rejects on network errors. A 404 or 500 response still resolves! Always check res.ok or res.status.

POST Request

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

  if (!res.ok) {
    const error = await res.json();
    throw new Error(error.message);
  }

  return res.json();
}

// Usage
const newUser = await createUser({ name: 'Alice', email: 'alice@example.com' });

Proper Error Handling

async function apiFetch(url, options = {}) {
  const res = await fetch(url, options);

  if (!res.ok) {
    let message = `HTTP error ${res.status}`;
    try {
      const body = await res.json();
      message = body.message || message;
    } catch {}
    throw new Error(message);
  }

  const contentType = res.headers.get('content-type');
  if (contentType?.includes('application/json')) {
    return res.json();
  }
  return res.text();
}

Loading States

async function loadData() {
  const btn = document.getElementById('load-btn');
  const output = document.getElementById('output');

  btn.disabled = true;
  btn.textContent = 'Loading...';

  try {
    const data = await apiFetch('/api/data');
    output.innerHTML = renderData(data);
  } catch (err) {
    output.innerHTML = `<p class="error">${err.message}</p>`;
  } finally {
    btn.disabled = false;
    btn.textContent = 'Load Data';
  }
}

Aborting Requests

let controller;

async function search(query) {
  // Cancel previous request
  if (controller) controller.abort();
  controller = new AbortController();

  try {
    const res = await fetch(`/api/search?q=${query}`, {
      signal: controller.signal
    });
    return res.json();
  } catch (err) {
    if (err.name === 'AbortError') return; // Request was cancelled, ignore
    throw err;
  }
}