Ante
Ante

Reputation: 111

How to fetch the next set of results from a paginated API?

I'm fetching data from an API that is paginated server-side. I have limited the number of results to 5 (rows=5). For the first set of data, a global variable pageNumber has been declared to 1, and eventListeners for the Previous/Next buttons have been added. Now I don't know how to get the next set of results. They can be fetched by changing the pageNumber to 2 but I don't know how to access the URL from const endpoint where I would change the pageNumber parameters to get previous and/or next results. Any idea how to do that?

// First set of fetched data starts with page 1
let pageNumber = 1;

// 1. Define endpoint, fetch response and return data promise
const search = async (term) => {
    const key = 'aroplosuitin';

    const endpoint = `https://api.europeana.eu/record/v2/search.json`,
        query = `?wskey=${key}&query=${term}&start=${pageNumber}&rows=5&profile=rich'`;

    const response = await fetch(endpoint + query);

    // Check response status:
    if (response.status !== 200) {
        throw new Error('Cannot fetch data. Response status is not 200.');
    }

    const data = await response.json();

    return data;
};

// 2. Call search and return data promise
const searchEuropeana = async (term) => {
    const data = await search(term);

    return data;
};

// 3. Grab the input and invoke callback to update the UI
const searchForm = document.querySelector('#search-form');

searchForm.addEventListener('submit', (e) => {
    e.preventDefault();

    // grab user input
    const userInput = searchForm.search.value.trim();
    // reset form on submit
    searchForm.reset();

    // For errors
    const errorOutput = document.querySelector('.error');

    // Invoke searchEuropeana
    searchEuropeana(userInput)
        .then((data) => {
            updateUI(data);
            console.log(data);
        })
        .catch((error) => {
            console.log('An error occured:', error),
                (errorOutput.innerText = 'Check your spelling or network.');
        });
});

// 4. Update the UI with HTML template
const updateUI = (data) => {
    console.log(data);
};

// 5. Previous / Next results
const previousBtn = document.querySelector('#previousBtn'),
    nextBtn = document.querySelector('#nextBtn');

previousBtn.addEventListener('click', () => {
    if (pageNumber > 1) {
        pageNumber--;
    } else {
        return;
    }
    console.log(pageNumber);
    searchEuropeana();
});

nextBtn.addEventListener('click', () => {
    pageNumber++;
    console.log(pageNumber);
    searchEuropeana();
});
        <main id="main">
                <h2>(Be)Heading</h2>
                <br>
                <section id="search">
                    <form id="search-form">
                        <div class="form-group search-group">
                            <input type="text" name="search" id="search" required>

                            <button id="searchButton" class="btn" type="submit">Search</button>
                        </div>
                    </form>
                </section>

                <br>

                <section id="output">
                    <!-- Error messages -->
                    <div class="error"></div>
                </section>        
                
                <button id="previousBtn" class="btn" type="submit">Previous</button>
                <button id="nextBtn" class="btn" type="submit">Next</button>
        </main>

Upvotes: 1

Views: 3017

Answers (1)

AdityaParab
AdityaParab

Reputation: 7100

// First set of fetched data starts with page 1
let pageNumber = 1;
let term = '';

// 1. Define endpoint, fetch response and return data promise
const search = async () => {
    const key = 'aroplosuitin';

    const endpoint = `https://api.europeana.eu/record/v2/search.json`,
        query = `?wskey=${key}&query=${term}&start=${pageNumber}&rows=5&profile=rich'`;

    const response = await fetch(endpoint + query);

    // Check response status:
    if (response.status !== 200) {
        throw new Error('Cannot fetch data. Response status is not 200.');
    }

    const data = await response.json();

    return data;
};

// 2. Call search and return data promise
const searchEuropeana = async () => {
    const data = await search();

    return data;
};

// 3. Grab the input and invoke callback to update the UI
const searchForm = document.querySelector('#search-form');

searchForm.addEventListener('submit', (e) => {
    e.preventDefault();

    // grab user input
    term = searchForm.search.value.trim();
    // reset form on submit
    searchForm.reset();

    // For errors
    const errorOutput = document.querySelector('.error');

    // Invoke searchEuropeana
    searchEuropeana()
        .then((data) => {
            updateUI(data);
            console.log(data);
        })
        .catch((error) => {
            console.log('An error occured:', error),
                (errorOutput.innerText = 'Check your spelling or network.');
        });
});

// 4. Update the UI with HTML template
const updateUI = (data) => {
    console.log(data);
};

// 5. Previous / Next results
const previousBtn = document.querySelector('#previousBtn'),
    nextBtn = document.querySelector('#nextBtn');

previousBtn.addEventListener('click', () => {
    if (pageNumber > 1) {
        pageNumber--;
    } else {
        return;
    }
    console.log(pageNumber);
    searchEuropeana();
});

nextBtn.addEventListener('click', () => {
    pageNumber++;
    console.log(pageNumber);
    searchEuropeana();
});

EDIT:

Take a look at a more readable approach

// First set of fetched data starts with page 1

const searchFormEl = document.querySelector("#search-form");
const errorEl = document.querySelector(".query");
const nextBtn = document.querySelector("#nextBtn");
const prevBtn = document.querySelector("#previousBtn");
const searchEl = document.querySelector("#search");
let pageNumber = 1;

const getApiUrl = () => {
  const key = "aroplosuitin";
  const endPoint = `https://api.europeana.eu/record/v2/search.json`;
  const query = `?wskey=${key}&query=${searchEl.value.trim()}&start=${pageNumber}&rows=5&profile=rich'`;
  return `${endPoint}${query}`;
};

// 1. Define endpoint, fetch response and return data promise
const search = async () => {
  const response = await fetch(getApiUrl());

  // Check response status:
  if (response.status !== 200) {
    throw new Error("Cannot fetch data. Response status is not 200.");
  }

  const data = await response.json();

  return data;
};

// 2. Call search and return data promise
const searchEuropeana = async () => await search();

// 3. Grab the input and invoke callback to update the UI

searchFormEl.addEventListener("submit", (e) => {
  e.preventDefault();

  // Invoke searchEuropeana
  searchEuropeana()
    .then((data) => {
      updateUI(data);
      console.log(data);
      searchFormEl.reset();
    })
    .catch((error) => {
      console.log("An error occured:", error);
      errorEl.innerText = "Check your spelling or network.";
    });
});

// 4. Update the UI with HTML template
const updateUI = (data) => {
  console.log(data);
};

prevBtn.addEventListener("click", () => {
  pageNumber = pageNumber > 1 ? pageNumber - 1 : pageNumber;
  searchEuropeana().then(updateUI);
});

nextBtn.addEventListener("click", () => {
  pageNumber++;
  searchEuropeana().then(updateUI);
});

Upvotes: 1

Related Questions