Why are duplicate calls being made?
Because the render callback is called for all request types - that is display
, filter
, sort
and type
. In your case it is called initially twice per row
- one time for
display
, i.e retrieving the data
- a second time for
filter
since you have a order on the columns, at least the default order
Obviously anything than the first AJAX request is redundant. Normally you can avoid consecutively requests simply by testing on the type
, but you have a setup with AJAX where values should be injected delayed.
The solution you have above by inserting success.mydate
via DOM is actually the worse part: It will never work since any value is forgotten on next draw. And you cannot simply return success.mydate
either (classic async problem)
I will suggest you maintain a list of processed (ajaxed) values in meta.settings.aoColumns[]
(so you can have multiple columns with that setup in the same table).
As mentioned in the first answer, check if type
is of kind display
; this is the very first request and the only one you want / need to process.
Then check if you already have processed the column for the row, if not do the ajax stuff and in done()
update both the processed value and the cell through the API!
Meanwhile return a dummy string or perhaps the initial value of data
.
In all other cases, return the processed value from meta.settings.aoColumns[]
I cannot replicate your setup above accurately, but here is the scheme :
render: function(data, type, row, meta) {
if (!meta.settings.aoColumns[meta.col]._processed) {
meta.settings.aoColumns[meta.col]._processed = []
}
var processed = meta.settings.aoColumns[meta.col]._processed
if (type == 'display') {
if (!processed[meta.row]) {
processed[meta.row] = 'waiting ...' + meta.row
$.ajax({
url : 'https://api.myjson.com/bins/avxod'
}).done(function(success) {
var fakeVal = 'Ok, done '+meta.row //success.mydate
processed[meta.row] = fakeVal
//update through the API
$('#example')
.DataTable()
.cell({ row: meta.row, column: meta.col })
.data( fakeVal )
.invalidate()
})
return processed[meta.row]
} else {
return processed[meta.row]
}
} else {
return processed[meta.row]
}
}
I believe it is pretty fail proof. Here is a demo -> http://jsfiddle.net/0bsbw6gt/