Skip to content
intermediatePhase 33 · Advanced JavaScript

Fetch API

Make HTTP requests with fetch, handle responses, and work with JSON data.

45m
0 problems
Topic Progress0%

Making Requests

The Fetch API provides a modern way to make HTTP requests. It returns a Promise that resolves to a Response object.

Basic GET Request

fetch('https://api.example.com/users')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

With async/await

async function getUsers() {
  try {
    const response = await fetch('https://api.example.com/users');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Failed to fetch users:', error);
  }
}

POST Request

async function createUser(userData) {
  const response = await fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(userData)
  });
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return response.json();
}

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

Other HTTP Methods

// PUT
await fetch(url, { method: 'PUT', body: data });

// PATCH
await fetch(url, { method: 'PATCH', body: data });

// DELETE
await fetch(url, { method: 'DELETE' });

// HEAD
await fetch(url, { method: 'HEAD' });

Handling Responses

The Response object has methods to read the response body in different formats.

Response Properties

const response = await fetch('/api/data');

console.log(response.ok);       // true if status 200-299
console.log(response.status);   // 200
console.log(response.statusText); // 'OK'
console.log(response.headers);  // Headers object
console.log(response.url);      // Final URL after redirects
console.log(response.type);     // 'basic', 'cors', etc.

Response Methods

// JSON
const data = await response.json();

// Text
const text = await response.text();

// Blob (for files, images)
const blob = await response.blob();

// ArrayBuffer (for binary data)
const buffer = await response.arrayBuffer();

// FormData
const formData = await response.formData();

Checking Response Status

async function fetchData() {
  const response = await fetch('/api/data');
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return response.json();
}

Handling Different Status Codes

async function fetchWithStatusHandling() {
  const response = await fetch('/api/data');
  
  switch (response.status) {
    case 200:
      return response.json();
    case 304:
      return null; // Not modified
    case 401:
      throw new Error('Unauthorized');
    case 404:
      throw new Error('Not found');
    case 500:
      throw new Error('Server error');
    default:
      throw new Error(`Unexpected status: ${response.status}`);
  }
}

Advanced Fetch Patterns

Real-world fetch usage often requires patterns for timeouts, abort controllers, and retry logic.

Request Timeout

function fetchWithTimeout(url, options = {}, timeout = 5000) {
  return Promise.race([
    fetch(url, options),
    new Promise((_, reject) =>
      setTimeout(() => reject(new Error('Request timeout')), timeout)
    )
  ]);
}

// Usage
try {
  const data = await fetchWithTimeout('/api/slow', {}, 3000);
} catch (error) {
  console.error(error.message); // 'Request timeout'
}

Abort Controller

const controller = new AbortController();
const signal = controller.signal;

// Start request
fetch('/api/data', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Request cancelled');
    } else {
      console.error('Fetch error:', error);
    }
  });

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

Retry Logic

async function fetchWithRetry(url, options = {}, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url, options);
      if (response.ok) return response;
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(r => setTimeout(r, 1000 * (i + 1)));
    }
  }
  throw new Error('Max retries reached');
}

Interceptors Pattern

async function fetchWithInterceptors(url, options = {}) {
  // Pre-request interceptor
  const modifiedOptions = { ...options };
  modifiedOptions.headers = {
    ...modifiedOptions.headers,
    'Authorization': `Bearer ${getToken()}`
  };
  
  const response = await fetch(url, modifiedOptions);
  
  // Post-response interceptor
  if (response.status === 401) {
    await refreshToken();
    return fetch(url, modifiedOptions); // Retry
  }
  
  return response;
}

Practice Problems

0/3solved
Build Fetch API Component

Create a reusable React component implementing Fetch API. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Fetch API Testing

Write unit and integration tests for Fetch API using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Fetch API Performance

Optimize Fetch API for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What does fetch() return?

Question 1 options

2. How do you check if a fetch response was successful?

Question 2 options

3. How do you cancel a fetch request?

Question 3 options

4. What happens if fetch() encounters a network error?

Question 4 options

Flashcards

Question

What is the Fetch API?

Answer

A modern API for making HTTP requests that returns a Promise resolving to a Response object.

Question

How to read JSON from a fetch response?

Answer

await response.json() - it also returns a Promise.

Question

What is response.ok?

Answer

A boolean that's true if the HTTP status is 200-299 (success range).

Question

How to cancel a fetch request?

Answer

Use AbortController: const controller = new AbortController(); fetch(url, { signal: controller.signal }); controller.abort();

Question

What is Fetch API?

Answer

Fetch API is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.fetch() returns a Promise that resolves to a Response object
  • 2.Always check response.ok or response.status before reading the body
  • 3.Use AbortController to cancel requests
  • 4.Network errors reject the Promise, they don't return error status codes
  • 5.Use async/await with fetch for cleaner code

Interview Tips

  • Explain the difference between fetch errors and HTTP error status codes
  • Demonstrate how to implement a request timeout
  • Discuss when to use AbortController
  • Compare fetch with XMLHttpRequest or axios

Cheat Sheet

Fetch API Cheat Sheet

Basic Request

const response = await fetch(url);
const data = await response.json();

POST Request

await fetch(url, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(data)
});

Response Properties

  • response.ok - true if 200-299
  • response.status - HTTP status code
  • response.headers - Response headers

Response Methods

  • .json() - Parse as JSON
  • .text() - Parse as text
  • .blob() - Parse as Blob

Advanced

  • AbortController for cancellation
  • Promise.race() for timeouts