George Katsanos George Katsanos - 1 month ago 13
jQuery Question

Infinite scrolling from two different API endpoints

The question could also be titled "attaching two different scroll Event Handlers on

window
and programmatically switching between them

I have two endpoints, the first one brings me a list of "latest" items:

/api/latest.json


and the other one is used to perform a search to all items:

/api/items.json?q="mission+impossible"


Both endpoints accept a "page_limit" parameter, as well as a "page" parameter, so:

/api/latest.json?page_limit=10&page=1


will fetch the first page of items, capping to 10 items.

Here is the scenario:


  1. As soon as my page loads (assume it's an onLoad/documentLoaded) only the first page of latest items is loaded

  2. A scroll event handler is attached to the window which takes care of infinite scrolling



window.addEventListener('scroll', throttle(() => this.handleScroll('api/latest.json'), 450))


handleScroll()
takes care of looking when the bottom of the page was reached and if so executes
getItems()
which takes as parameters the url, the page number, and the number of items per page, as well as increases the page_number variable internally.

All this works fine.

Here is where things get tricky:


  1. The user performs a search (uses the second endpoint)

  2. All results are updated (it's a SPA using Vue.js)

  3. The user scrolls down

  4. When the bottom of the page is reached, a new request is made BUT

  5. it is not the second page of
    /api/items.json?page_number=2&q="mission+impossible"
    but the one from
    /api/latest.json?page_number=2



So, in theory, the handleScroll function, should be aware (with some Vue.js magic probably) of the current context:


  • did the user perform a search or

  • is he staring at the initially loaded page of latest.json


Answer

Your question is somewhat unclear, but it sounds like you want to have one of two actions fire. The easiest way to accomplish this, would be to write a scroll handler that can decide which action to fire, and then run it accordingly. In the following example I am running them in sequence, but you could decide based on other state if necessary.

For example:

 var handlers = [
    getItems('api/latest.json', 10, 1, 450),
    doSearch // handler involving your other endpoint
 ]
 var nextHandler = 0;

 function scrollHandler(e){
   handlers[nextHandler++](e);
   nextHandler = nextHandler % handlers.length; // wrap around if necessary
 }

 window.addEventListener('scroll', scrollHandler)