Zak
Zak

Reputation: 940

How to make pagination from an API with AJAX with the same query?

I don't know how good I could the write the title but it's a little bit complicated.

So I have this webpage in /music-maker endpoint which have a modal. In the modal there is an input field which takes in a user input and post it to the backend through AJAX post request. Then that user query is used to make an API request to https://example.com/api/?key=${key}&q=${query}. The result is then displayed in the webpage.

Now that part is working as it should be but the issue comes when I try to implement an infinite scrolling feature to it.

Please note at this point that the api request above returns the first page of data only and if I specify page 2 then it will return the data from page 2 of that exact query.

So whenever the user scrolls to the bottom I need to make another api request with that exact query as before but for page 2 which I am unable to accomplish. I've tried making a get AJAX request and used a global query variable to store the query from post request but it returns undefined.

Here are the endpoints of the app:

let query;

router.get('/music-maker', (req, res) => {
    res.render('music-maker');
});


router.post('/music-maker', async (req, res) => {
    query           = encodeURI(req.body.input);

    const key = '205XxXxX54825-0ab1';

    try{
        const url       = `https://example.com/api/?key=${key}&q=${query}`;
        const fullRes   = await axios.get(url);

        if( fullRes.status === 200 ) {

            return res.json({ 
                data: fullRes.data
            });
        
        }

    }catch(err) {
        res.json({
            error: 'Unable to retrieve data.'
        });
    }

});


router.get('/music-maker/page', async (req, res) => {
    console.log('1: ', query); // returns undefined
    const pageQuery         = req.query.q;

    try{
        console.log('2: ', pageQuery)
    }catch(err) {
        console.log(err)
    }

});

Here are the AJAX requests:

const formInput         = $(".searchbar input");
const userSearchInput   = formInput.val();
const modalForm         = $("form");
    
$(modalForm).submit((e) => {
      e.preventDefault();
      const actionUrl = $(e.target).attr("action");
        
      $.ajax({
            type: "POST",
            url: actionUrl,
            dataType: "json",
            data: {
                input: userSearchInput
            },
            beforeSend: function() {
                $(formInput).val("");
            },
            success: function({ data }) {
                if ( data ) {
                    $(".data-container").html(data);
                } else if (data.error) {
                    $(".error-container").html(data.error);
                }
            },
            complete: function() {
                $(".loader-container").addClass("hidden");
            },
      });
});

// When the user scrolls to the bottom of the container, this ajax request fires

$('.data-container').on('scroll', function(e) {
        const elem = $(e.currentTarget);
        if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {

            console.log(userSearchInput); // this is undefined

            $.ajax({
                type: "GET",
                url: `/music-maker/page/`,
                dataType: "json",
                beforeSend: function() {
                    console.log('sending');
                },
                success: function( data ) {
                    console.log('incoming');
                },
                complete: function() {
                    console.log('complete');
                },
            });

       }
});

How can I get the other pages' data of the same query by making an API request through AJAX?

Upvotes: 1

Views: 3024

Answers (1)

uingtea
uingtea

Reputation: 6534

update:

server part code

router.get("/music-maker/search/:query/:page", async (req, res) => {
  let query = req.params.query;
  let page = req.params.page;
  console.log("query: " + query);
  console.log("page: " + page);
  
  return res.json({
    query: req.params.query,
    page: req.params.page
  });
});

client/browser

let userSearchInput = "";
let pageNumber = 1;

function getMusicMaker() {
  userSearchInput = $(".searchbar input").val();
  userSearchInput = encodeURIComponent(userSearchInput);
  const actionUrl = "/music-maker/search";
  
  $.ajax({
    url: `${actionUrl}/${userSearchInput}/${pageNumber}`,
    dataType: "json",
    beforeSend: function () {
      $(".searchbar input").val("");
    },
    success: function (data) {
      alert(data.query + "\n" + data.page)
    }
  });
}
$("form").submit((e) => {
  e.preventDefault();
  pageNumber = 1; // new search, reset page number
  getMusicMaker();
});


$(".data-container").on("scroll", function (e) {
  const elem = $(e.currentTarget);
  if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {
    pageNumber++; // set page 2,3,4,....
    getMusicMaker();
  }
});

I think you have multiple problems, to fix it need whole rewrite to your code (client and server) but I suggest to use single http method, POST or GET.

endpoint for static pages list:

/music-maker/1
/music-maker/2
or
/music-maker = /music-maker/page/1
/music-maker/page/2

for search

/music-maker/search/keywords
/music-maker/search/keywords/2
/music-maker/search/keywords/3

to set page number when user scroll you can do like this

let pageNumber = 1;

$('.data-container').on('scroll', function (e) {
  const elem = $(e.currentTarget);
  
  if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {

    pageNumber++;
    
    $.ajax({
      type: "GET",
      url: `/music-maker/page/${pageNumber}`,
      .......
    });
  }
});

Upvotes: 1

Related Questions