mpen
mpen

Reputation: 282885

How to refresh DataTables from within ajax/error callback?

I'm extending the DataTables defaults like so:

$.extend(true, $.fn.dataTable.defaults, {
    lengthChange: false,
    deferRender: true,
    displayLength: 25,
    stateSave: false,
    serverSide: true,
    processing: true,
    ajax: {
        type: 'POST',
        error: function($xhr) {
            if($xhr.status === 401) {
                wxu.openLoginBox(function(data) {
                    // HELP: how can I get the DataTables object from this context?
                });
            } else {
                wxu.notify({'text': "Could not load list", 'cssClass': 'error', timeout: 0});
            }
        }
    }
});

Sometimes a user will get logged out and then when they try changing pages or sorting, it just says "Processing" forever. I can catch this by looking for a 401 error response (this is what my app sends when you've been timed out), but then I don't know how to "refresh" dataTables to make the "Processing" message go away so that you can resume using the app.

Please note that I'm extending the defaults here in a .js file -- I don't know what element DataTables is going to be bound to at this point.

How can I "fix" dataTables from inside the ajax/error callback?

Upvotes: 3

Views: 6342

Answers (2)

Gyrocode.com
Gyrocode.com

Reputation: 58880

NOTES

You should not override ajax.error since this property is used internally by DataTables, the same applies to ajax.success.

SOLUTION

You can add event handler for xhr event to handle Ajax errors (json === null).

// Prevent alert message from being displayed
$.fn.dataTable.ext.errMode = 'none';

// Use delegated event handler
// to handle Ajax request completion event
$(document.body).on('xhr.dt', function (e, settings, json, xhr){
   // If there is an Ajax error and status code is 401
   if(json === null && xhr.status === 401){         
      var api = new $.fn.dataTable.Api(settings);

      console.log('Session expired');
/*     
      wxu.openLoginBox(function(data){
          api.ajax.reload();
      });
*/

   } else {
      console.log('Could not load list');   
/*       
       wxu.notify({'text': "Could not load list", 'cssClass': 'error', timeout: 0});
*/       
   }
});

DEMO

See this jsFiddle for code and demonstration.

Upvotes: 3

Chris Hunt
Chris Hunt

Reputation: 4030

Per the documentation, ajax can be a function. It is called with the table settings object, which can be used to construct a new API object for the table. Then, you can just use the API method to get the processing element (using .dataTables_processing) or take whatever other action you like using the other available API methods. Concretely, something like this should work:

{
  "ajax": function (data, callback, settings) {
    $.ajax({
      type: "POST",
      success: function (json) {
        callback(json);
      },
      error: function ($xhr) {
        if ($xhr.status === 401) {
          var api = new $.fn.dataTable.Api(settings);
          var container = api.table().container();
          $(container).find('.dataTables_processing').hide();
        }
      }
    });
  }
}

I don't see it documented specifically, but this is also set to the DataTable object in the ajax function when it is called. Using that could be a more direct route to your goal, but I think the above aligns more with the intended use.

Upvotes: 2

Related Questions