Web Fetch API

Make HTTP requests and handle responses with modern JavaScript

🌐 What is the Fetch API?

The Fetch API provides a modern way to make HTTP requests in JavaScript. It's a promise-based alternative to XMLHttpRequest, making it easier to work with APIs and handle responses.


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

Output:

Users: [{id: 1, name: "John"}, {id: 2, name: "Jane"}]

Request completed successfully!

HTTP Methods with Fetch

📥

GET Request

Retrieve data from server

fetch('/api/data')
📤

POST Request

Send data to server

fetch('/api/users', {method: 'POST'})
✏️

PUT Request

Update existing data

fetch('/api/users/1', {method: 'PUT'})
🗑️

DELETE Request

Remove data from server

fetch('/api/users/1', {method: 'DELETE'})

🔹 Basic GET Request

Fetching data from an API:

// Simple GET request
async function fetchUsers() {
    try {
        const response = await fetch('https://jsonplaceholder.typicode.com/users');
        
        // Check if request was successful
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const users = await response.json();
        console.log('Users loaded:', users.length);
        
        // Display users
        displayUsers(users);
        
    } catch (error) {
        console.error('Failed to fetch users:', error);
        document.getElementById('error').textContent = 'Failed to load users';
    }
}

function displayUsers(users) {
    const userList = document.getElementById('user-list');
    userList.innerHTML = users.map(user => `
        <div class="user-card">
            <h3>${user.name}</h3>
            <p>Email: ${user.email}</p>
            <p>City: ${user.address.city}</p>
        </div>
    `).join('');
}

// Call the function
fetchUsers();

User List Demo:

John Doe

Email: [email protected]

City: New York

🔹 POST Request with Data

Sending data to a server:

// POST request to create new user
async function createUser(userData) {
    try {
        const response = await fetch('https://jsonplaceholder.typicode.com/users', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(userData)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const newUser = await response.json();
        console.log('User created:', newUser);
        return newUser;
        
    } catch (error) {
        console.error('Failed to create user:', error);
        throw error;
    }
}

// Example usage
async function handleFormSubmit() {
    const formData = {
        name: document.getElementById('name').value,
        email: document.getElementById('email').value,
        phone: document.getElementById('phone').value
    };
    
    try {
        const newUser = await createUser(formData);
        alert('User created successfully!');
        
        // Clear form
        document.getElementById('user-form').reset();
        
    } catch (error) {
        alert('Failed to create user. Please try again.');
    }
}

// Form submission
document.getElementById('user-form').addEventListener('submit', function(e) {
    e.preventDefault();
    handleFormSubmit();
});

Create User Form:




🔹 Handling Different Response Types

Fetch can handle various response formats:

// Handle JSON response
async function fetchJSON(url) {
    const response = await fetch(url);
    const data = await response.json();
    return data;
}

// Handle text response
async function fetchText(url) {
    const response = await fetch(url);
    const text = await response.text();
    return text;
}

// Handle blob (for images, files)
async function fetchImage(url) {
    const response = await fetch(url);
    const blob = await response.blob();
    
    // Create image URL
    const imageUrl = URL.createObjectURL(blob);
    
    // Display image
    const img = document.createElement('img');
    img.src = imageUrl;
    document.body.appendChild(img);
    
    return blob;
}

// Handle form data
async function fetchFormData(url) {
    const response = await fetch(url);
    const formData = await response.formData();
    return formData;
}

// Check response type and handle accordingly
async function smartFetch(url) {
    const response = await fetch(url);
    const contentType = response.headers.get('content-type');
    
    if (contentType && contentType.includes('application/json')) {
        return await response.json();
    } else if (contentType && contentType.includes('text/')) {
        return await response.text();
    } else {
        return await response.blob();
    }
}

Response Types:

  • .json(): Parse JSON data
  • .text(): Get plain text
  • .blob(): Binary data (images, files)
  • .formData(): Form data
  • .arrayBuffer(): Raw binary data

🔹 Request Configuration

Customize requests with headers, authentication, and more:

// Advanced fetch configuration
async function advancedFetch() {
    const options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer your-token-here',
            'X-Custom-Header': 'custom-value'
        },
        body: JSON.stringify({
            name: 'John Doe',
            email: '[email protected]'
        }),
        mode: 'cors', // cors, no-cors, same-origin
        credentials: 'include', // include, same-origin, omit
        cache: 'no-cache', // default, no-cache, reload, force-cache
        redirect: 'follow', // manual, follow, error
        referrerPolicy: 'no-referrer' // no-referrer, origin, etc.
    };
    
    try {
        const response = await fetch('https://api.example.com/users', options);
        
        // Check response status
        if (response.status === 401) {
            throw new Error('Unauthorized - check your token');
        }
        
        if (response.status === 404) {
            throw new Error('Resource not found');
        }
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const data = await response.json();
        return data;
        
    } catch (error) {
        console.error('Request failed:', error);
        throw error;
    }
}

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

Request Options:

✅ Custom headers for authentication

✅ CORS configuration

✅ Credential handling

✅ Cache control

✅ Timeout handling

🔹 Error Handling Best Practices

Robust error handling for fetch requests:

// Comprehensive error handling
async function robustFetch(url, options = {}) {
    try {
        // Check if browser supports fetch
        if (!window.fetch) {
            throw new Error('Fetch API not supported');
        }
        
        const response = await fetch(url, options);
        
        // Handle different error scenarios
        if (!response.ok) {
            // Create detailed error message
            let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
            
            // Try to get error details from response
            try {
                const errorData = await response.json();
                if (errorData.message) {
                    errorMessage += ` - ${errorData.message}`;
                }
            } catch (e) {
                // Response is not JSON, use status text
            }
            
            throw new Error(errorMessage);
        }
        
        return response;
        
    } catch (error) {
        // Handle different types of errors
        if (error.name === 'TypeError') {
            // Network error or CORS issue
            throw new Error('Network error - check your connection');
        } else if (error.message.includes('timeout')) {
            throw new Error('Request timed out - server is slow');
        } else {
            // Re-throw other errors
            throw error;
        }
    }
}

// Usage with user feedback
async function loadDataWithFeedback() {
    const loadingElement = document.getElementById('loading');
    const errorElement = document.getElementById('error');
    const dataElement = document.getElementById('data');
    
    try {
        // Show loading
        loadingElement.style.display = 'block';
        errorElement.style.display = 'none';
        
        const response = await robustFetch('/api/data');
        const data = await response.json();
        
        // Show data
        dataElement.innerHTML = JSON.stringify(data, null, 2);
        
    } catch (error) {
        // Show error
        errorElement.textContent = error.message;
        errorElement.style.display = 'block';
        
    } finally {
        // Hide loading
        loadingElement.style.display = 'none';
    }
}

Error Handling Demo:

Loading...
Error message would appear here
Data would be displayed here

🧠 Test Your Knowledge

Which method is used to parse JSON from a fetch response?