Mapagam
  • JavaScript 
  • Web APIs 
  • TypeScript 
  • React 

How to Use the JavaScript Fetch API for Real-World HTTP Requests

Posted on April 18, 2025 • 5 min read • 907 words
Share via
Mapagam
Link copied to clipboard

Master the JavaScript Fetch API with real-world examples, async/await, React integration, and best practices for modern web apps.

On this page
1. Introduction: Why the Fetch API Matters 2. Getting Started with Fetch 2.1 Basic GET Request 2.2 Using async/await for Cleaner Code 3. Real-World Use Cases 3.1 Submitting Data with POST 3.2 Updating Resources with PUT and PATCH 3.3 Deleting Resources 4. Fetch API in React 4.1 Fetching Data in useEffect 4.2 Handling Loading and Error States 5. Advanced Fetch Patterns 5.1 Timeout with AbortController 5.2 Retrying Failed Requests 6. Pitfalls and Best Practices 7. Practice Prompts 8. Conclusion and Further Reading

1. Introduction: Why the Fetch API Matters

If you’re building modern web applications with React, plain JavaScript, or even TypeScript, handling HTTP requests is inevitable. Whether you’re fetching data from a REST API, submitting a form, or integrating with a third-party service, knowing how to use the fetch API efficiently is essential. The Fetch API is a modern, promise-based way to make HTTP requests, and it’s widely supported across browsers.

Many developers rely on Axios or other libraries, but the native Fetch API is powerful and capable enough for most needs. Learning how to harness its capabilities directly gives you a lighter, more performant app without extra dependencies.

This guide will walk you through practical, real-world use cases of the Fetch API, from simple GET requests to advanced use with async/await, error handling, and integration with frontend frameworks like React.

2. Getting Started with Fetch

2.1 Basic GET Request

Let’s begin with a basic example: fetching a list of posts from a placeholder API.

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

This code fetches posts and logs them to the console. Notice how it chains promises to handle asynchronous flow. fetch returns a Promise that resolves to a Response object, and response.json() returns another promise.

2.2 Using async/await for Cleaner Code

async function getPosts() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    const posts = await response.json();
    console.log(posts);
  } catch (error) {
    console.error('Error fetching posts:', error);
  }
}

getPosts();

Async/await makes asynchronous code look synchronous and improves readability, especially in complex flows.

3. Real-World Use Cases

3.1 Submitting Data with POST

async function createPost(post) {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(post),
  });

  const data = await response.json();
  console.log('Created Post:', data);
}

createPost({ title: 'New Post', body: 'Hello world', userId: 1 });

This is how you send data using the POST method. Always include the Content-Type header when sending JSON.

3.2 Updating Resources with PUT and PATCH

async function updatePost(id, updatedFields) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
    method: 'PATCH',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(updatedFields),
  });

  const data = await response.json();
  console.log('Updated Post:', data);
}

updatePost(1, { title: 'Updated Title' });

PATCH allows partial updates, while PUT requires replacing the entire object.

3.3 Deleting Resources

async function deletePost(id) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
    method: 'DELETE',
  });

  if (response.ok) {
    console.log(`Post ${id} deleted successfully.`);
  } else {
    console.error('Failed to delete post');
  }
}

deletePost(1);

4. Fetch API in React

4.1 Fetching Data in useEffect

import React, { useEffect, useState } from 'react';

function PostList() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
        const data = await response.json();
        setPosts(data);
      } catch (error) {
        console.error('Error fetching posts:', error);
      }
    };

    fetchData();
  }, []);

  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

This example shows how to use Fetch in a useEffect hook to load data when the component mounts.

4.2 Handling Loading and Error States

function PostList() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
        if (!response.ok) throw new Error('Failed to fetch');
        const data = await response.json();
        setPosts(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchPosts();
  }, []);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;

  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

5. Advanced Fetch Patterns

5.1 Timeout with AbortController

async function fetchWithTimeout(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) {
    if (error.name === 'AbortError') {
      console.error('Fetch timed out');
    } else {
      console.error('Fetch error:', error);
    }
  }
}

fetchWithTimeout('https://jsonplaceholder.typicode.com/posts');

Using AbortController is essential for handling timeouts and cancellations.

5.2 Retrying Failed Requests

async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error('Fetch failed');
      return await response.json();
    } catch (err) {
      if (i < retries - 1) {
        console.warn(`Retrying... (${i + 1})`);
      } else {
        throw err;
      }
    }
  }
}

Retries are useful for transient errors like network failures.

6. Pitfalls and Best Practices

  • Always check response.ok: Don’t assume the response was successful just because it resolved.
  • Use try...catch around fetch**: Fetch only throws for network errors, not HTTP errors.
  • Avoid memory leaks in React: Use cleanup functions or AbortController to cancel requests.
  • Be cautious with CORS: Fetch respects browser CORS rules. The server must allow your origin.

7. Practice Prompts

  • Modify a React component to fetch users from an API and display their emails.
  • Create a mini form that sends a POST request and shows the response below.
  • Add loading, error, and success states to a fetch call in TypeScript.

8. Conclusion and Further Reading

The Fetch API is a fundamental tool for frontend developers working with Web APIs. From basic requests to advanced patterns like retries and cancellation, mastering fetch can make your applications faster, more reliable, and easier to maintain.

Key Takeaways:

  • Fetch is native, modern, and widely supported.
  • Use async/await for readability.
  • Handle errors and loading states properly.
  • Integrate with React via useEffect and hooks.
  • Apply best practices to avoid bugs and improve UX.
Fetch Api   Javascript Http Requests   React Data Fetching   Async Await   Web Api Fetch  
Fetch Api   Javascript Http Requests   React Data Fetching   Async Await   Web Api Fetch  
 Beginner’s Guide to the JavaScript DOM API (With Practical Examples)
How to Open and Close Browser Windows Using the Window API 
On this page:
1. Introduction: Why the Fetch API Matters 2. Getting Started with Fetch 2.1 Basic GET Request 2.2 Using async/await for Cleaner Code 3. Real-World Use Cases 3.1 Submitting Data with POST 3.2 Updating Resources with PUT and PATCH 3.3 Deleting Resources 4. Fetch API in React 4.1 Fetching Data in useEffect 4.2 Handling Loading and Error States 5. Advanced Fetch Patterns 5.1 Timeout with AbortController 5.2 Retrying Failed Requests 6. Pitfalls and Best Practices 7. Practice Prompts 8. Conclusion and Further Reading
Follow me

I work on everything coding and technology

   
Mapagam
Mapagam is your go-to resource for all things related to frontend development. From the latest frameworks and libraries to tips, tutorials, and best practices, we dive deep into the ever-evolving world of web technologies.
Licensed under Creative Commons (CC BY-NC-SA 4.0).
 
Frontend
JavaScript 
Web Api 
TypeScript 
React 
Social
Linkedin 
Github 
Mapagam
Code copied to clipboard