Explain the Fetch API and how it differs from XMLHttpRequest. Provide examples of common use cases.

3 minintermediatejavascriptes6fetchapidiffersxmlhttprequest

Quick Answer

The Fetch API is a modern, promise-based interface for making HTTP requests that replaces the older XMLHttpRequest.

Detailed Answer

The Fetch API is a modern, promise-based interface for making HTTP requests that replaces the older XMLHttpRequest.

Basic Fetch Usage:

// Simple GET request
async function fetchUser(id) {
  try {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Fetch failed:', error);
    throw error;
  }
}

// POST request with JSON
async function createUser(userData) {
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify(userData)
  });
  return await response.json();
}

Fetch vs XMLHttpRequest:

// XMLHttpRequest (old way)
function fetchUserXHR(id) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', `/api/users/${id}`);
    xhr.onload = function() {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject(new Error(`HTTP ${xhr.status}: ${xhr.statusText}`));
      }
    };
    xhr.onerror = function() {
      reject(new Error('Network error'));
    };
    xhr.send();
  });
}

// Fetch API (modern way)
async function fetchUserFetch(id) {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  return await response.json();
}

Advanced Features:

// AbortController for cancellation
async function fetchWithAbort(url, timeout = 5000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);
  
  try {
    const response = await fetch(url, { signal: controller.signal });
    clearTimeout(timeoutId);
    return await response.json();
  } catch (error) {
    clearTimeout(timeoutId);
    if (error.name === 'AbortError') {
      throw new Error('Request was aborted');
    }
    throw error;
  }
}