How to avoid multiple refresh?

How to avoid multiple refresh?

luisrortegaluisrortega Posts: 79Questions: 6Answers: 1

Hi, I'm looking into a design issue that is NOT an issue with DataTables, but I figure other developers probably had the same situation.

I have a series of DataTables (server-side) refreshing out of a timer. The problem is that if the server takes too long to respond, the browser does not care at all. It just triggers the timer over and over again. This by itself, hammer the servers even more!

I have a few ideas of how to get around, but none of them are "pretty"... They are kind of hammers, and I wonder if anyone has a more elegant solution.

Suggestions...

  1. Create a "processing" variable, and set/check its value before submit an "$('#tbl_content').DataTable().ajax.reload(null, false), and clear after data has been received.

This approach will work, however, it's a bit of a pain to do per each component. I wonder if there is a way to know the status of the ajax request already available?

  1. Instead of setInterval, use setTimeout and retrigger it after a result... That way the software will not keep pushing requests after requests to the server.

  2. Create some kind of extension to DataTable, where I can pass the "setAutoRefresh" seconds, and it will...

    • Create an Interval, and attach it to the instance. Follow the 2nd suggestion, but with all elements attached to the current data table...
    • OnInterval... call ajax.reload, and recreate the interval
    • have a "clearAutoRefresh" to directly clear the interval directly

Any suggestion is always welcome!

Luis

Answers

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    One option might be to use the xhr event and in the event use setTimeout to trigger the next reload.

    Kevin

  • luisrortegaluisrortega Posts: 79Questions: 6Answers: 1

    Shut, that might be a cleaner... way...

    setAutoRefresh(dataTable)
    - trap event for xhr
    - create setTimeout
    - on timeout call ajax.reload, then reset setTimeout to call itself...

    I need to figure what to do if there is a communication error (since xhr might not trigger)

  • luisrortegaluisrortega Posts: 79Questions: 6Answers: 1

    This is surely not the most beautiful code you will see today... whatever...

    jQuery.fn.extend({
      autoRefresh: function(refreshRate) {
          const refreshData = function (dt){
            $(dt).DataTable().ajax.reload(null, false);
          }
          const fnRefreshData = function (e, settings, json) {
             if (e.target.autoRefreshElement.refreshRate !== 0){
                 e.target.autoRefreshElement.interval = setTimeout(refreshData, e.target.autoRefreshElement.refreshRate,e.target);
                 $(e.target).one('xhr.dt',fnRefreshData);
             }
          };
    
        return this.each(function(index, eachitem) {
          let item = $(eachitem)[0];
          console.log('test item is...' , item.autoRefreshElement);
          if (!item.autoRefreshElement){
            console.log('new item is...' , item);
          
            item.autoRefreshElement = {
                interval : setTimeout(refreshData, refreshRate, item),
                refreshRate : refreshRate
            }
            $(item).one('xhr.dt',fnRefreshData);
          }
          else{
            console.log('reset item is...' , item);
            item.autoRefreshElement.refreshRate = refreshRate;// set new (for next trigger)
          }
        });
      }
    });
    
    

    to call it.. use...

    $('#tbl-customers-content').autoRefresh(10000)
    

    Thanks,
    Luis

  • luisrortegaluisrortega Posts: 79Questions: 6Answers: 1

    Is there a way for me to attach it to DataTables itself? so instead of

    $('#tbl-customers-content').autoRefresh(10000)
    

    we can use...

    $('#tbl-customers-content').DataTables().autoRefresh(10000) 
    
  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    we can use...
    $('#tbl-customers-content').DataTables().autoRefresh(10000)

    No because $('#tbl-customers-content').DataTables() returns an instance of the (Datatables API](https://datatables.net/manual/api#Accessing-the-API) which doesn't have an aPI like autoRefresh().

    Kevin

  • luisrortegaluisrortega Posts: 79Questions: 6Answers: 1

    a couple of modifications

    • Validate the object is an actual dataTable by using $.fn.dataTable.isDataTable(item)
    • Extend dataTable object (instead of core JQuery)
    jQuery.fn.dataTable().extend({
      autoRefresh: function(refreshRate) {
          const refreshData = function (dt){
            $(dt).DataTable().ajax.reload(null, false);
          }
    
          const fnRefreshData = function (e, settings, json) {
             if (e.target.autoRefreshElement.refreshRate !== 0){
                 e.target.autoRefreshElement.interval = setTimeout(refreshData, e.target.autoRefreshElement.refreshRate,e.target);
                 $(e.target).one('xhr.dt',fnRefreshData);
             }
          };
    
        return this.each(function(index, eachitem) {
          let item = $(eachitem)[0];
          if ($.fn.dataTable.isDataTable(item)){
          console.log('test item is...' , item.autoRefreshElement);
          if (!item.autoRefreshElement){
            console.log('new item is...' , item);
          
            item.autoRefreshElement = {
                interval : setTimeout(refreshData, refreshRate, item),
                refreshRate : refreshRate
            }
            $(item).one('xhr.dt',fnRefreshData);
          }
          else{
            console.log('reset item is...' , item);
            item.autoRefreshElement.refreshRate = refreshRate;// set new (for next trigger)
          }
          }
        });
       }
    });
    

    now...

    $('#tbl-customers-content').dataTables().autoRefresh(10000);
    
  • luisrortegaluisrortega Posts: 79Questions: 6Answers: 1

    Ups sorry Kevin, I didn't read your message on time... I took the plugin route to use the internal API... I'm not sure if this is future proof, but it works as of now :smile:

    Thanks for your help!

This discussion has been closed.