Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
LoginSign Up
menu
  1. Home
  2. /Web Development
  3. /Javascript
  4. /Fetch Api Http Requests
Your Progress0%
0 of 61 completed

JavaScript Topics

Getting Started

  • What is JavaScript?
  • JavaScript vs Other Languages
  • Setting Up Your JavaScript Environment
  • Developer Console and Debugging Basics

JavaScript Fundamentals

  • Variables (var, let, const)
  • Data Types and Type Checking
  • Comments and Code Organization
  • String Methods and Template Literals
  • Type Conversion and Coercion
  • Operators (Arithmetic, Comparison, Logical)

Control Flow

  • If/Else Statements
  • Switch Statements
  • Ternary Operator
  • Truthy and Falsy Values
  • Logical Operators and Short-Circuiting

Loops and Iteration

  • For Loops
  • While and Do-While Loops
  • For...of and For...in Loops
  • Break and Continue Statements

Functions

  • Function Declarations and Expressions
  • Arrow Functions
  • Function Parameters and Arguments
  • Return Statements and Values
  • Scope and Closures
  • Higher-Order Functions and Callbacks

Arrays

  • Array Basics and Creation
  • Array Methods: Adding and Removing Elements
  • Array Iteration Methods (forEach, map, filter)
  • Array Methods: find, some, every, reduce
  • Sorting, Reversing, and Array Transformation

Objects

  • Object Basics and Properties
  • Object Methods and 'this' Keyword
  • Object Destructuring
  • Object.keys, values, entries
  • Spread Operator and Object Cloning

DOM Manipulation

  • Introduction to the DOM
  • Selecting Elements (querySelector, getElementById)
  • Modifying Elements (textContent, innerHTML, style)
  • Creating and Removing Elements
  • Event Listeners and Event Handling
  • Event Object and Event Delegation

Asynchronous JavaScript

  • Understanding Asynchronous Code
  • setTimeout and setInterval
  • Callbacks and Callback Hell
  • Promises and Promise Chaining
  • Async/Await

Error Handling

  • Try, Catch, Finally
  • Throwing Custom Errors

Modern JavaScript Features

  • ES6+ Overview
  • Modules (import/export)
  • Optional Chaining and Nullish Coalescing
  • Rest and Spread Operators

Working with Data

  • JSON (Parse and Stringify)
  • Fetch API and HTTP Requests
  • Working with Local Storage

Advanced Concepts

  • Classes and Object-Oriented Programming
  • Array and Object Advanced Patterns
  • Regular Expressions Basics

Best Practices & Real-World Application

  • JavaScript Best Practices
  • Debugging Techniques and Tools
  • Building a Complete Interactive Project

Fetch API and HTTP Requests

Making API calls and handling responses

Modern web applications communicate with servers through HTTP requests— fetching data, submitting forms, updating resources, and more. The Fetch API is JavaScript's modern, Promise-based interface for making HTTP requests. It replaces the older XMLHttpRequest with a cleaner, more powerful API. Whether you're calling REST APIs, loading data, or building full-stack applications, mastering fetch() is essential. Let's learn to fetch like a pro!

What is the Fetch API?

Fetch API Features:

  • Modern replacement for XMLHttpRequest
  • Returns Promises (works great with async/await)
  • Supports all HTTP methods (GET, POST, PUT, DELETE, etc.)
  • Handles different response types (JSON, text, blob)
  • Built into modern browsers (no library needed)
  • Flexible configuration (headers, body, credentials)

Basic GET Request

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

// With async/await (cleaner!)
async function getUsers() {
  try {
    let response = await fetch('https://api.example.com/users');
    let data = await response.json();
    console.log('Users:', data);
    return data;
  } catch (error) {
    console.error('Error:', error);
    return null;
  }
}

// Call the function
let users = await getUsers();

// Real-world example: Load posts
async function loadPosts() {
  try {
    let response = await fetch('https://jsonplaceholder.typicode.com/posts');
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    let posts = await response.json();
    return posts;
  } catch (error) {
    console.error('Failed to load posts:', error);
    return [];
  }
}

let posts = await loadPosts();
console.log(`Loaded ${posts.length} posts`);

Understanding the Response Object

JAVASCRIPT
async function exploreResponse() {
  let response = await fetch('https://api.example.com/users');
  
  // Response properties
  console.log('Status:', response.status);        // 200, 404, 500, etc.
  console.log('Status Text:', response.statusText);  // "OK", "Not Found"
  console.log('OK:', response.ok);                // true if 200-299
  console.log('URL:', response.url);              // Final URL
  console.log('Headers:', response.headers);      // Headers object
  
  // Response methods (each can only be called once!)
  let json = await response.json();      // Parse as JSON
  // let text = await response.text();   // Get as text
  // let blob = await response.blob();   // Get as binary data
  // let buffer = await response.arrayBuffer();  // Get as ArrayBuffer
  
  return json;
}

// Check response status
async function getUserById(id) {
  let response = await fetch(`https://api.example.com/users/${id}`);
  
  if (response.ok) {
    // Status 200-299
    let user = await response.json();
    return user;
  } else if (response.status === 404) {
    console.log('User not found');
    return null;
  } else if (response.status === 500) {
    console.log('Server error');
    return null;
  } else {
    console.log(`Unexpected status: ${response.status}`);
    return null;
  }
}

// Read headers
async function checkHeaders() {
  let response = await fetch('https://api.example.com/users');
  
  console.log('Content-Type:', response.headers.get('Content-Type'));
  console.log('Date:', response.headers.get('Date'));
  
  // Check if JSON
  let contentType = response.headers.get('Content-Type');
  if (contentType && contentType.includes('application/json')) {
    let data = await response.json();
    return data;
  } else {
    let text = await response.text();
    return text;
  }
}

HTTP Methods (CRUD Operations)

GET - Retrieve Data

JAVASCRIPT
// GET request (default method)
async function getUser(userId) {
  let response = await fetch(`https://api.example.com/users/${userId}`);
  
  if (!response.ok) {
    throw new Error('Failed to fetch user');
  }
  
  let user = await response.json();
  return user;
}

// GET with query parameters
async function searchUsers(query) {
  // Build URL with query parameters
  let params = new URLSearchParams({
    q: query,
    limit: 10,
    page: 1
  });
  
  let response = await fetch(`https://api.example.com/users?${params}`);
  let results = await response.json();
  return results;
}

// Usage
let user = await getUser(123);
let results = await searchUsers('alice');

POST - Create Data

JAVASCRIPT
// POST request - create new resource
async function createUser(userData) {
  try {
    let 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}`);
    }
    
    let newUser = await response.json();
    console.log('User created:', newUser);
    return newUser;
  } catch (error) {
    console.error('Failed to create user:', error);
    throw error;
  }
}

// Usage
let newUser = await createUser({
  name: 'Alice',
  email: 'alice@example.com',
  age: 25
});

// POST with form data
async function uploadFile(file) {
  let formData = new FormData();
  formData.append('file', file);
  formData.append('description', 'My file');
  
  let response = await fetch('https://api.example.com/upload', {
    method: 'POST',
    body: formData  // Don't set Content-Type header with FormData!
  });
  
  let result = await response.json();
  return result;
}

PUT/PATCH - Update Data

JAVASCRIPT
// PUT - replace entire resource
async function updateUser(userId, userData) {
  let response = await fetch(`https://api.example.com/users/${userId}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(userData)
  });
  
  if (!response.ok) {
    throw new Error('Failed to update user');
  }
  
  let updatedUser = await response.json();
  return updatedUser;
}

// PATCH - update specific fields
async function patchUser(userId, updates) {
  let response = await fetch(`https://api.example.com/users/${userId}`, {
    method: 'PATCH',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(updates)
  });
  
  let updatedUser = await response.json();
  return updatedUser;
}

// Usage
// PUT - replace entire user
await updateUser(123, {
  name: 'Alice Smith',
  email: 'alice@example.com',
  age: 26
});

// PATCH - update only age
await patchUser(123, {
  age: 26
});

DELETE - Remove Data

JAVASCRIPT
// DELETE request
async function deleteUser(userId) {
  try {
    let response = await fetch(`https://api.example.com/users/${userId}`, {
      method: 'DELETE'
    });
    
    if (!response.ok) {
      throw new Error('Failed to delete user');
    }
    
    // Some APIs return no content (204)
    if (response.status === 204) {
      return true;
    }
    
    // Others return confirmation
    let result = await response.json();
    return result;
  } catch (error) {
    console.error('Delete failed:', error);
    return false;
  }
}

// Usage
let success = await deleteUser(123);
if (success) {
  console.log('User deleted');
}

Request Configuration

Headers

JAVASCRIPT
// Setting request headers
async function fetchWithAuth() {
  let response = await fetch('https://api.example.com/protected', {
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN_HERE',
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'X-Custom-Header': 'custom-value'
    }
  });
  
  let data = await response.json();
  return data;
}

// Headers object (alternative)
let headers = new Headers();
headers.append('Authorization', 'Bearer TOKEN');
headers.append('Content-Type', 'application/json');

let response = await fetch('https://api.example.com/data', { headers });

// Dynamic headers
function getHeaders(includeAuth = true) {
  let headers = {
    'Content-Type': 'application/json'
  };
  
  if (includeAuth) {
    let token = localStorage.getItem('authToken');
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }
  }
  
  return headers;
}

// Usage
let response = await fetch('/api/users', {
  headers: getHeaders()
});

Request Options

JAVASCRIPT
// Complete request configuration
async function configuredFetch() {
  let response = await fetch('https://api.example.com/data', {
    method: 'POST',           // HTTP method
    headers: {                // Request headers
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({    // Request body
      name: 'Alice'
    }),
    mode: 'cors',             // cors, no-cors, same-origin
    credentials: 'include',   // include, same-origin, omit
    cache: 'no-cache',        // default, no-cache, reload, force-cache
    redirect: 'follow',       // follow, error, manual
    referrerPolicy: 'no-referrer'  // Referrer policy
  });
  
  return response.json();
}

// Credentials (cookies)
// 'include' - send cookies even cross-origin
// 'same-origin' - send cookies only same-origin (default)
// 'omit' - never send cookies

async function fetchWithCookies() {
  let response = await fetch('https://api.example.com/user', {
    credentials: 'include'  // Include cookies
  });
  return response.json();
}

Error Handling

JAVASCRIPT
// Comprehensive error handling
async function robustFetch(url, options = {}) {
  try {
    let response = await fetch(url, options);
    
    // Check if response is OK (200-299)
    if (!response.ok) {
      // Try to get error message from response
      let errorData;
      try {
        errorData = await response.json();
      } catch {
        errorData = { message: response.statusText };
      }
      
      throw new Error(
        `HTTP ${response.status}: ${errorData.message || 'Request failed'}`
      );
    }
    
    // Parse response based on content type
    let 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();
    }
  } catch (error) {
    // Network errors, timeouts, etc.
    if (error.name === 'TypeError') {
      console.error('Network error:', error);
      throw new Error('Network error. Check your connection.');
    }
    
    // HTTP errors
    if (error.message.startsWith('HTTP')) {
      console.error('HTTP error:', error);
      throw error;
    }
    
    // Other errors
    console.error('Unexpected error:', error);
    throw new Error('An unexpected error occurred.');
  }
}

// Usage with specific error handling
async function loadUserData(userId) {
  try {
    let user = await robustFetch(`/api/users/${userId}`);
    return user;
  } catch (error) {
    if (error.message.includes('404')) {
      alert('User not found');
    } else if (error.message.includes('500')) {
      alert('Server error. Please try again later.');
    } else if (error.message.includes('Network')) {
      alert('No internet connection');
    } else {
      alert('Failed to load user');
    }
    return null;
  }
}

// Timeout wrapper
async function fetchWithTimeout(url, options = {}, timeout = 5000) {
  let controller = new AbortController();
  let timeoutId = setTimeout(() => controller.abort(), timeout);
  
  try {
    let response = await fetch(url, {
      ...options,
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    return response;
  } catch (error) {
    clearTimeout(timeoutId);
    if (error.name === 'AbortError') {
      throw new Error('Request timeout');
    }
    throw error;
  }
}

// Usage
try {
  let response = await fetchWithTimeout('/api/data', {}, 3000);
  let data = await response.json();
} catch (error) {
  console.error(error.message);
}

Practical Examples

Example 1: User Management API

JAVASCRIPT
// Complete User API client
class UserAPI {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }
  
  async request(endpoint, options = {}) {
    let url = `${this.baseURL}${endpoint}`;
    
    let config = {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...options.headers
      }
    };
    
    try {
      let response = await fetch(url, config);
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      
      return await response.json();
    } catch (error) {
      console.error('API Error:', error);
      throw error;
    }
  }
  
  // GET all users
  async getUsers() {
    return this.request('/users');
  }
  
  // GET single user
  async getUser(id) {
    return this.request(`/users/${id}`);
  }
  
  // POST create user
  async createUser(userData) {
    return this.request('/users', {
      method: 'POST',
      body: JSON.stringify(userData)
    });
  }
  
  // PUT update user
  async updateUser(id, userData) {
    return this.request(`/users/${id}`, {
      method: 'PUT',
      body: JSON.stringify(userData)
    });
  }
  
  // DELETE user
  async deleteUser(id) {
    return this.request(`/users/${id}`, {
      method: 'DELETE'
    });
  }
  
  // Search users
  async searchUsers(query) {
    let params = new URLSearchParams({ q: query });
    return this.request(`/users/search?${params}`);
  }
}

// Usage
let api = new UserAPI('https://api.example.com');

// Get all users
let users = await api.getUsers();

// Create user
let newUser = await api.createUser({
  name: 'Alice',
  email: 'alice@example.com'
});

// Update user
await api.updateUser(newUser.id, {
  name: 'Alice Smith'
});

// Delete user
await api.deleteUser(newUser.id);

// Search
let results = await api.searchUsers('alice');

Example 2: Loading Indicators

JAVASCRIPT
// Fetch with loading state
class DataLoader {
  constructor() {
    this.loading = false;
  }
  
  async fetchWithLoading(url, options = {}) {
    this.showLoading();
    
    try {
      let response = await fetch(url, options);
      
      if (!response.ok) {
        throw new Error('Request failed');
      }
      
      let data = await response.json();
      this.hideLoading();
      return data;
    } catch (error) {
      this.hideLoading();
      this.showError(error.message);
      throw error;
    }
  }
  
  showLoading() {
    this.loading = true;
    let loader = document.getElementById('loader');
    if (loader) {
      loader.style.display = 'block';
    }
  }
  
  hideLoading() {
    this.loading = false;
    let loader = document.getElementById('loader');
    if (loader) {
      loader.style.display = 'none';
    }
  }
  
  showError(message) {
    alert(`Error: ${message}`);
  }
}

// Usage
let loader = new DataLoader();

async function loadData() {
  try {
    let data = await loader.fetchWithLoading('/api/data');
    displayData(data);
  } catch (error) {
    console.error('Failed to load data');
  }
}

Example 3: Parallel Requests

JAVASCRIPT
// Load multiple resources in parallel
async function loadDashboard(userId) {
  try {
    // Start all requests simultaneously
    let [user, posts, comments, stats] = await Promise.all([
      fetch(`/api/users/${userId}`).then(r => r.json()),
      fetch(`/api/posts?userId=${userId}`).then(r => r.json()),
      fetch(`/api/comments?userId=${userId}`).then(r => r.json()),
      fetch(`/api/stats?userId=${userId}`).then(r => r.json())
    ]);
    
    return { user, posts, comments, stats };
  } catch (error) {
    console.error('Failed to load dashboard:', error);
    throw error;
  }
}

// Usage
let dashboard = await loadDashboard(123);
console.log('User:', dashboard.user.name);
console.log('Posts:', dashboard.posts.length);

// Handle partial failures with Promise.allSettled
async function loadDashboardSafe(userId) {
  let results = await Promise.allSettled([
    fetch(`/api/users/${userId}`).then(r => r.json()),
    fetch(`/api/posts?userId=${userId}`).then(r => r.json()),
    fetch(`/api/comments?userId=${userId}`).then(r => r.json())
  ]);
  
  let data = {};
  
  results.forEach((result, index) => {
    if (result.status === 'fulfilled') {
      let keys = ['user', 'posts', 'comments'];
      data[keys[index]] = result.value;
    } else {
      console.error(`Failed to load ${['user', 'posts', 'comments'][index]}`);
    }
  });
  
  return data;
}

Fetch API and HTTP Requests

Master API calls

Output:
Click "Run" to execute your code...
💡 Tip: Use console.log() to see your output in the console above.

Key Takeaways

  • fetch() makes HTTP requests and returns a Promise
  • Response object has status, ok, headers, and parsing methods
  • response.json() parses JSON (also returns Promise)
  • GET retrieves, POST creates, PUT/PATCH updates, DELETE removes
  • Set method, headers, and body in options object
  • Always check response.ok before parsing
  • Use try-catch for network and HTTP errors
  • Headers object for authentication, content-type, etc.
  • Promise.all() for parallel requests
  • Works best with async/await for clean code

What's Next?

You now understand the Fetch API and can make HTTP requests to servers! You've learned GET, POST, PUT, DELETE requests, error handling, and practical patterns for building API-connected applications.

In the next lesson, we'll explore Working with Local Storage—learning to store and retrieve data in the browser, creating persistent user experiences!

💪 Practice Challenge:

Before moving on, try:

  1. Make a GET request to a public API
  2. Create a POST request with JSON body
  3. Build a user API client with all CRUD operations
  4. Add proper error handling to all requests
  5. Load multiple resources in parallel with Promise.all()

Test Your Understanding

Question 1 / 4

What does the Fetch API do?

Score: 0 / 0

Mastering the Fetch API! 🌐

Previous
JSON (Parse and Stringify)
Next
Working with Local Storage

Continue Learning JavaScript

Join 2,000+ developers mastering JavaScript. New lessons weekly - 100% FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

JavaScript Tutorials

0 of 61 completed

Your Progress0%

Topics

Getting Started

  • What is JavaScript?
  • JavaScript vs Other Languages
  • Setting Up Your JavaScript Environment
  • Developer Console and Debugging Basics

JavaScript Fundamentals

  • Variables (var, let, const)
  • Data Types and Type Checking
  • Comments and Code Organization
  • String Methods and Template Literals
  • Type Conversion and Coercion
  • Operators (Arithmetic, Comparison, Logical)

Control Flow

  • If/Else Statements
  • Switch Statements
  • Ternary Operator
  • Truthy and Falsy Values
  • Logical Operators and Short-Circuiting

Loops and Iteration

  • For Loops
  • While and Do-While Loops
  • For...of and For...in Loops
  • Break and Continue Statements

Functions

  • Function Declarations and Expressions
  • Arrow Functions
  • Function Parameters and Arguments
  • Return Statements and Values
  • Scope and Closures
  • Higher-Order Functions and Callbacks

Arrays

  • Array Basics and Creation
  • Array Methods: Adding and Removing Elements
  • Array Iteration Methods (forEach, map, filter)
  • Array Methods: find, some, every, reduce
  • Sorting, Reversing, and Array Transformation

Objects

  • Object Basics and Properties
  • Object Methods and 'this' Keyword
  • Object Destructuring
  • Object.keys, values, entries
  • Spread Operator and Object Cloning

DOM Manipulation

  • Introduction to the DOM
  • Selecting Elements (querySelector, getElementById)
  • Modifying Elements (textContent, innerHTML, style)
  • Creating and Removing Elements
  • Event Listeners and Event Handling
  • Event Object and Event Delegation

Asynchronous JavaScript

  • Understanding Asynchronous Code
  • setTimeout and setInterval
  • Callbacks and Callback Hell
  • Promises and Promise Chaining
  • Async/Await

Error Handling

  • Try, Catch, Finally
  • Throwing Custom Errors

Modern JavaScript Features

  • ES6+ Overview
  • Modules (import/export)
  • Optional Chaining and Nullish Coalescing
  • Rest and Spread Operators

Working with Data

  • JSON (Parse and Stringify)
  • Fetch API and HTTP Requests
  • Working with Local Storage

Advanced Concepts

  • Classes and Object-Oriented Programming
  • Array and Object Advanced Patterns
  • Regular Expressions Basics

Best Practices & Real-World Application

  • JavaScript Best Practices
  • Debugging Techniques and Tools
  • Building a Complete Interactive Project
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo