How to Use the JavaScript Fetch API

If you’re building anything on the web—whether it’s a small frontend project or a production-ready app—you’ll eventually need to fetch data from an API. And for that, fetch() is one of the most simple & essential tools in JavaScript.

In this post, we’ll walk through how fetch() works, common mistakes, how to use it correctly, and tips for writing cleaner, more reliable code in real projects.

What is fetch() ?

JavaScript Fetch API

fetch() is a built-in JavaScript function that lets you make HTTP requests.
It returns a Promise and replaces older methods like XMLHttpRequest.

Here’s the basic syntax:

JavaScript
fetch(url, options)
  .then(response => response.json())
  .then(data => {
    // Do something with the data
  })
  .catch(error => {
    // Handle network errors
  });
  • url: the endpoint you want to call
  • options: (optional) an object for method, headers, body, etc.

Basic Usage Examples

1. GET request

This is the most basic use — fetching data from an API.

JavaScript
fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(res => res.json())
  .then(data => console.log(data.title));

This example fetches a single post from a fake API and logs the title.

2. POST request

JavaScript
fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Hello Fetch',
    body: 'This is a test post.',
    userId: 1,
  }),
})
  .then(res => res.json())
  .then(data => console.log(data));
  • You set ‘Content-Type’ to ‘application/json’
  • You use JSON.stringify() for the body

Error Handling

The Fetch API does not throw an error for HTTP errors by default. To handle them properly:

JavaScript
async function getPost() {
  try {
    const res = await fetch('https://api.example.com/post/1');
    if (!res.ok) {
      throw new Error(`Server error: ${res.status}`);
    }
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error('Fetch failed:', err);
  }
}

Common mistakes

1. fetch() doesn’t throw errors on 404 or 500

JavaScript
fetch('/not-found')
  .then(res => {
    if (!res.ok) throw new Error('Server error');
    return res.json();
  })
  .catch(err => console.error(err));

fetch() only throws an error for network-level issues (e.g., DNS failure, CORS).
HTTP status errors like 404 or 500 won’t trigger .catch() you need to check res.ok


2. Response body can only be read once

JavaScript
const res = await fetch(...);
const data = await res.json(); // OK
const text = await res.text(); // Error: body already used

You can either read the body as .json(), .text(), or .blob(), but only once.


3. CORS issues

Cross-origin requests may be blocked by the server unless it explicitly allows them via headers like:

JavaScript
Access-Control-Allow-Origin: *

If you’re calling an external API and hitting CORS errors, it’s likely the server doesn’t allow public access.


4. Cookies are not included by default

JavaScript
fetch('/api/user', {
  credentials: 'include',
});

Use the credentials option if your app uses session-based auth (e.g., with cookies).

  • ‘omit’ (default): don’t send cookies
  • ‘same-origin’: send cookies for same-origin requests
  • ‘include’: send cookies always (even cross-origin)

5. No built-in timeout

fetch() does not timeout on its own. Use AbortController to cancel a long request:

JavaScript
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000); // 5s timeout

fetch('/slow-api', { signal: controller.signal })
  .catch(err => {
    if (err.name === 'AbortError') console.log('Request timed out');
  });

✔️ async/await vs then/catch

You can use either style with fetch. async/await is cleaner for complex flows:

JavaScript
async function loadData() {
  try {
    const res = await fetch('/api/data');
    if (!res.ok) throw new Error('Something went wrong');
    const json = await res.json();
    console.log(json);
  } catch (err) {
    console.error('Error:', err);
  }
}

fetch vs axios

Featurefetchaxios
Built-in✅ Yes❌ Requires install
Auto JSON parsing❌ No (use .json())✅ Yes
Timeout support❌ No✅ Yes
Interceptors❌ No✅ Yes
Cookie handlingManual (credentials)Automatic

Test APIs for Practice

Here are two free APIs you can use while learning fetch:

Great for testing GET and POST requests without setting up a backend.

Leave a Comment