Search code examples
javascriptperformancedatepickerflatpickr

Showing occupancy in flatpickr asynchronously without swamping server with requests


I'm trying to build a calendar by means of flatpickr which shows the occupancy in the month-view. The little dots in this datepicker:

enter image description here

The docs of flatpickr state a fairly simple way to interact with the day-cell, and add some elements or manipulate the cell at the moment the day-cell is created:

...
onDayCreate: function(dObj, dStr, fp, dayElem){
    // Utilize dayElem.dateObj, which is the corresponding Date

    // dummy logic
    if (Math.random() < 0.15)
        dayElem.innerHTML += "<span class='event'></span>";

    else if (Math.random() > 0.85)
        dayElem.innerHTML += "<span class='event busy'></span>";
}
...

Pretty cool: this callback is called every time the cell is created, so 30|31 times per view.

The occupancy is exposed through an API which takes a single or an array of dates, and it returns an array with occupancy info:

{
  '2018-04-19': 60,
  '2018-04-30': 21,
  ....
}

In the onDayCreate-event I could call for the API and act according the returned result. Although this creates 30/31 requests it's doable, but not very efficient.

So far so good; but the problem lies with the fact if you scroll through the months, each month is generating 30/31 requests to the API. Even if the month is only showed for a fraction of a second. Essentially I'm DDOSsing my own server.

My next approach was to preload the 'first' month in 1 request and use the onDayCreate-event to cherrypick from the preloaded array.

The occupancy of succeeding months would be async loaded in the onMonthChange-event. But, flatpickr seems to fire the onMonthChange-event and carry on with the day-creation:

enter image description here
Above the red line: initial month; below I clicked next month.

So I can't use the newly loaded data in the onMonthChange...

Any help on how I could dynamically load the occupancy info into flatpickr without overloading the API with (unnecessary) requests


Solution

  • Use the Day-created event to create elements like

    `<span data-date="${yourDate}" class='loading event'></span>`
    

    Then inside of the MonthChanged event process all of the elements that are loading and event class, querying all dates from an array of the attribute data-date.