Skip to content

Working with the Fetch API

  • The Fetch API is a modern JavaScript interface for making HTTP requests to HTTP servers.
  • It provides a cleaner, more flexible, and promise-based alternative to the older XMLHttpRequest.
  • With Fetch, you can easily retrieve data, send form submissions, upload files, and interact with APIs.

fetch(url, options)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
  • url: The endpoint you want to request
  • options (optional): Request configuration object for method, headers, body, etc.

  • A Promise is a JavaScript object that represents a value that isn’t available yet but will be at some point in the future.
  • When you call fetch(), the request takes time to reach the server and come back.
  • Instead of freezing the page while waiting, JavaScript gives you a Promise, a placeholder that says “I’ll have the result for you later.”

A Promise can be in one of three states:

  • Pending: The operation is still in progress.
  • Fulfilled: The operation completed successfully, and the result is available.
  • Rejected: The operation failed, and an error is available.

You handle Promises using .then() and .catch():

fetch('https://api.example.com/planets')
.then(response => response.json()) // runs when the request succeeds
.catch(error => console.error(error)); // runs if something goes wrong

Or using async/await, which is the modern approach covered later on this page.


Fetching JSON data from an API:

fetch('https://api.example.com/planets')
.then(response => response.json())
.then(planets => {
console.log(planets);
// Display planets on the page
})
.catch(error => console.error('Failed to fetch planets:', error));

Key points:

  • fetch() returns a Promise
  • .json() parses the response body as JSON (also returns a Promise)
  • Use .catch() to handle errors

Making a GET request using async/await.

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

Benefits:

  • Cleaner and more readable code
  • Easier error handling with try/catch
  • Works better with multiple sequential requests

Sending data to an HTTP server using a POST request.

Example: Sending a POST request to create a planet
async function createPlanet(planetData) {
try {
const response = await fetch('https://api.example.com/planets', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(planetData)
});
const result = await response.json();
console.log('Planet created:', result);
} catch (error) {
console.error('Error creating planet:', error);
}
}
createPlanet({
name: 'Earth',
system: 'Solar System',
distanceFromStar: 149.6,
radius: 6371,
mass: 5.972e24,
habitable: true,
discoveryDate: '1543-05-24'
});

Important:

  • Specify method: 'POST'
  • Set appropriate headers
  • Convert JavaScript objects to JSON with JSON.stringify()

fetch() only rejects on network failures (e.g., no internet). It does not reject on HTTP errors like 404 or 500. You need to check response.ok yourself:

async function fetchPlanets() {
try {
const response = await fetch('https://api.example.com/planets');
// fetch() doesn't reject on HTTP errors — check manually
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
return data;
} catch (error) {
if (error.name === 'TypeError') {
// Network error or CORS issue — request never reached the server
console.error('Network error or CORS issue');
} else {
// HTTP error or parsing error
console.error('Fetch error:', error.message);
}
}
}

Key response properties:

  • response.ok: true if status is 200-299
  • response.status: HTTP status code (200, 404, 500, etc.)
  • response.statusText: Status message (“OK”, “Not Found”, etc.)

The response body can be parsed in different ways depending on what the server returns:

// JSON response (most common for APIs)
const data = await response.json();
// Plain text
const text = await response.text();

The following is an example of a live search feature using the Fetch API, allowing users to search for planets by name.

Example: Live search feature using the Fetch API
const searchInput = document.getElementById('search');
const resultsDiv = document.getElementById('results');
// AJAX triggering action: on keypress (as you type the search query)
searchInput.addEventListener('keypress', async (e) => {
const query = e.target.value;
if (query.length < 3) return; // Wait for at least 3 characters
try {
const response = await fetch(`https://api.example.com/planets?q=${query}`);
const results = await response.json();
// AJAX response: the search results are displayed in the resultsDiv
resultsDiv.innerHTML = results
.map(item => `<div class="result">${item.name}</div>`)
.join('');
} catch (error) {
resultsDiv.innerHTML = '<p>Search failed. Please try again.</p>';
}
});

Configuring a fetch request with common options:

fetch(url, {
method: 'POST', // HTTP method
headers: { // Request headers
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
},
body: JSON.stringify(data), // Request body
mode: 'cors', // cors, no-cors, same-origin
credentials: 'include', // include, same-origin, omit
cache: 'no-cache' // Cache mode
});

MethodPurposeHas Body
GETRetrieve dataNo
POSTCreate new resourceYes
PUTUpdate entire resourceYes
PATCHUpdate partial resourceYes
DELETERemove resourceOptional