JavaScript · API · Beginner

Pagination

5 tasks

Iterate through multi-page API responses to collect all results.

How pagination works

#
The API returns results 20 at a time by default. The response includes `next` — a full URL for the next page, or `null` if you're on the last page: ```javascript { count: 372, next: "https://apilearn.tukas.dev/api/products/?page=2", previous: null, results: [ /* 20 products */ ] } ``` To get all products, keep following `next` until it's `null`: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function getAllProducts() { let url = `${BASE_URL}/api/products/`; const all = []; while (url) { const response = await fetch(url); const data = await response.json(); all.push(...data.results); url = data.next; // null on the last page → loop ends } return all; } ``` `...data.results` spreads the page's items into the `all` array. `url = data.next` moves to the next page. When `data.next` is `null`, the while condition is falsy and the loop exits. You can also request more results per page with `page_size`: ```javascript // Get 50 per page instead of 20 — fewer requests needed const params = new URLSearchParams({ page_size: 50 }); const response = await fetch(`${BASE_URL}/api/products/?${params}`); ``` Maximum `page_size` is 100.

Pagination patterns

#
Collect all products across all pages: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function getAllProducts() { let url = `${BASE_URL}/api/products/?page_size=100`; const all = []; while (url) { const response = await fetch(url); const data = await response.json(); all.push(...data.results); url = data.next; } console.log(`Loaded ${all.length} products total`); return all; } getAllProducts(); ``` Paginate with a callback -- process each page as it arrives: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function eachPage(baseUrl, callback) { let url = baseUrl; while (url) { const response = await fetch(url); const data = await response.json(); await callback(data.results, data.count); url = data.next; } } async function main() { await eachPage(`${BASE_URL}/api/products/`, (products, total) => { console.log(`Page of ${products.length} / ${total} total`); }); } main(); ``` Stop early after finding what you need: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function findProduct(name) { let url = `${BASE_URL}/api/products/`; while (url) { const response = await fetch(url); const data = await response.json(); const found = data.results.find(p => p.name === name); if (found) return found; url = data.next; } return null; } async function main() { const product = await findProduct('Tea Table Set with Three Chairs'); console.log(product ? product.price : 'not found'); } main(); ```

Pagination reference

#
**Paginated response shape** ```javascript { count: 372, // total items across all pages next: "...?page=2" | null, previous: "...?page=1" | null, results: [...] // items on this page } ``` **Parameters** ``` page Page number (default 1) page_size Items per page (default 20, max 100) ``` **Collect all pages pattern** ```javascript async function collectAll(startUrl) { const all = []; let url = startUrl; while (url) { const response = await fetch(url); const data = await response.json(); all.push(...data.results); url = data.next; } return all; } ``` **Reduce requests with page_size** ```javascript // 372 products at 20/page = 19 requests // 372 products at 100/page = 4 requests new URLSearchParams({ page_size: 100 }) ``` **Check if more pages exist** ```javascript if (data.next) { /* more pages */ } if (!data.next) { /* last page */ } ```
01

Fetch page 2

#

Fetch page 2 of `/api/products/` using the `page` parameter. Print the number of results on this page and the name of the first product.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // fetch page 2 and print results count + first product name
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const params = new URLSearchParams({ page: 2 });
  const response = await fetch(`${BASE_URL}/api/products/?${params}`);
  const data = await response.json();
  console.log(data.results.length);
  console.log(data.results[0].name);
}

main();
02

Follow next to get all pages

#

Write a loop that follows `data.next` until it's `null`. Count the total number of products collected across all pages and print it.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  let url = `${BASE_URL}/api/products/`;
  let total = 0;

  // loop: fetch url, add to total, set url = data.next
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  let url = `${BASE_URL}/api/products/`;
  let total = 0;

  while (url) {
    const response = await fetch(url);
    const data = await response.json();
    total += data.results.length;
    url = data.next;
  }

  console.log(total);
}

main();
03

Collect all products into an array

#

Write a `getAllProducts()` function that paginates through all pages with `page_size=100` and returns a single flat array of all products. Print the total length.

const BASE_URL = 'https://apilearn.tukas.dev';

async function getAllProducts() {
  // paginate with page_size=100, return flat array
}

async function main() {
  const all = await getAllProducts();
  console.log(all.length);
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function getAllProducts() {
  let url = `${BASE_URL}/api/products/?page_size=100`;
  const all = [];

  while (url) {
    const response = await fetch(url);
    const data = await response.json();
    all.push(...data.results);
    url = data.next;
  }

  return all;
}

async function main() {
  const all = await getAllProducts();
  console.log(all.length);
}

main();
04

Find the most expensive product

#

Load all products (paginate through all pages), then find the one with the highest price. Print its name and price.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // collect all products across pages
  // find the most expensive one
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  let url = `${BASE_URL}/api/products/?page_size=100`;
  const all = [];

  while (url) {
    const response = await fetch(url);
    const data = await response.json();
    all.push(...data.results);
    url = data.next;
  }

  const mostExpensive = all.reduce((max, p) =>
    parseFloat(p.price) > parseFloat(max.price) ? p : max
  );
  console.log(mostExpensive.name, mostExpensive.price);
}

main();
05

Count products per page

#

Fetch all pages of `/api/products/` with the default page size. For each page, print `"Page N: X products"`. Print the total at the end.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  let url = `${BASE_URL}/api/products/`;
  let page = 1;
  let total = 0;

  // loop pages and print info
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  let url = `${BASE_URL}/api/products/`;
  let page = 1;
  let total = 0;

  while (url) {
    const response = await fetch(url);
    const data = await response.json();
    console.log(`Page ${page}: ${data.results.length} products`);
    total += data.results.length;
    url = data.next;
    page++;
  }

  console.log(`Total: ${total} products across ${page - 1} pages`);
}

main();