> uploadtext_

v1.0.0 - Secure text sharing node

Fetching All Data from a Paginated API with Recursive Calls

Owner: SnippetBot Created: 2026-09-05 00:00:46 Size: 3.49 KB Expires: Never
[ RAW ] [ NEW ]
tty1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
/**
 * Fetches all items from a paginated API endpoint.
 * Assumes the API response structure includes:
 * - `results`: An array of items for the current page.
 * - `next`: A URL string for the next page, or null if it's the last page.
 * @param {string} initialUrl The first URL to fetch.
 * @param {RequestInit} [options] Fetch options.
 * @returns {Promise<Array<any>>} A promise that resolves with an array of all collected items.
 */
async function fetchAllPaginatedData(initialUrl, options = {}) {
  let allItems = [];
  let nextUrl = initialUrl;

  while (nextUrl) {
    try {
      console.log(`Fetching from: ${nextUrl}`);
      const response = await fetch(nextUrl, options);

      if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status} - ${response.statusText}`);
      }

      const data = await response.json();

      if (data && Array.isArray(data.results)) {
        allItems = allItems.concat(data.results);
      } else {
        console.warn('Paginated API response did not contain a "results" array or was unexpected.');
        // Optionally break or handle this non-standard response
      }

      nextUrl = data.next || null; // Move to the next page URL
    } catch (error) {
      console.error(`Error fetching paginated data from ${nextUrl}:`, error);
      throw error; // Re-throw to indicate failure
    }
  }

  return allItems;
}

// Usage example:
async function loadAllProducts() {
  const productsApiUrl = 'https://api.example.com/products?page=1'; // Example starting URL

  // Mock API response structure for demonstration
  // In a real scenario, this would be handled by the backend
  let mockPage = 1;
  const mockApiFetch = async (url) => {
    // Simulate API delay
    await new Promise(resolve => setTimeout(resolve, 500));

    if (url.includes('page=1') && mockPage === 1) {
      mockPage++;
      return {
        ok: true,
        json: async () => ({
          results: [{id: 1, name: 'Product A'}, {id: 2, name: 'Product B'}],
          next: 'https://api.example.com/products?page=2',
        }),
        status: 200,
        statusText: 'OK',
      };
    } else if (url.includes('page=2') && mockPage === 2) {
      mockPage++;
      return {
        ok: true,
        json: async () => ({
          results: [{id: 3, name: 'Product C'}, {id: 4, name: 'Product D'}],
          next: 'https://api.example.com/products?page=3',
        }),
        status: 200,
        statusText: 'OK',
      };
    } else if (url.includes('page=3') && mockPage === 3) {
      mockPage++;
      return {
        ok: true,
        json: async () => ({
          results: [{id: 5, name: 'Product E'}],
          next: null, // Last page
        }),
        status: 200,
        statusText: 'OK',
      };
    }
    return { ok: false, status: 404, statusText: 'Not Found', json: async () => ({ message: 'Page not found' }) };
  };

  // Temporarily override global fetch for demo purposes
  const originalFetch = globalThis.fetch;
  globalThis.fetch = mockApiFetch;

  try {
    const allProducts = await fetchAllPaginatedData(productsApiUrl, {
      // headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
    });
    console.log('All products:', allProducts);
    // Expected output:
    // [{id: 1, name: 'Product A'}, {id: 2, name: 'Product B'}, {id: 3, name: 'Product C'}, {id: 4, name: 'Product D'}, {id: 5, name: 'Product E'}]
  } catch (error) {
    console.error('Failed to fetch all products:', error);
  } finally {
    globalThis.fetch = originalFetch; // Restore original fetch
  }
}

loadAllProducts();