render with Ajax
render with Ajax
I have a table with a list of queries. One of the fields is the sql statement of the particular query. I would like to have a column of the data table return the count of records that query returns.
{
data: null, title: "# of Records", defaultContent: '<getting record count>',
render: function (data, type, row) {
if (type === 'display') {
var recCount=0;
console.log("data1", data.Statement)
if (data.Statement != null && data.Statement !='') {
console.log("getting count")
$.ajax({
url: "api/DynamicReturn?readText=" + data.Statement,
//async: false,
success: function (data) {
console.log("data2", data.data.length);
recCount = data.data.length;
}
})
return recCount;
} else {
return 'Not Developed yet';
}
}
},
className: "text-center"
},
This works fine if I use async: false. However, it takes forever to load initially. What would be awesome is that when the ajax is done, it goes back and updates the cell (I can put a 'calculating...' placeholder or something while it is loading.
Is this possible?
and a side question.... this render is being called twice per row, why is that? Is there more than one 'type ===display'
This question has an accepted answers - jump to answer
Answers
It is called multiple times to handle the different orthogonal data operations. You can use
console.log(type)
to see this. Its possible that the display operation is called more than once.Its not recommended to use an ajax call in
columns.render
for the reasons you are seeing. You would need to update the cell in thesuccess
function. It is possible, but not recommended, to update the cell using the values from themeta
parameter ofcolumns.render
.I would look at using
rowCallback
instead. It executes only when the row is displayed and is meant for dynamic updates like this. I would also look at keeping track of the fetcheddata.Statement
in an Object as a cache. Here is pseudo code:This will need some work to make it work but should give you an idea. You can add something to display 'calculating...' in the cell before the ajax call and remove it the success function.
Kevin
Not sure this is feasible with what you are trying to do but a better option might be to fetch all the
recCounts
and build thefetchedRecCounts
data structure when the table loads. Then all the data is at the client and quickly accessible when drawing the table data.Kevin
As always, you offered the perfect solution. thank you, it works nicely.
I am not sure what you mean by your last comment though.
Lets assume
url: "api/DynamicReturn
will return all the data, whatever that is, in a format that you can create an object with all the statements and their recCounts, for example:fetchedRecCounts = {statement1: 5, statement2: 10,....};
The basic flow would look like this:
Now you can use
columns.render
orrowCallback
to simply access the Javascript object fetchedRecCounts withdata.Statement
. IMHO its more efficient to fetch all the data up front and build some data structures for it than to individually fetch the data for each row. But your API might not support this or there might be too much data.Kevin
hmm. I will try and wrap my head around that method further
but, for now I am using your first suggestion. However, if I get an error trying to execute that dynamic sql statement my controller will return a -1. I then display a message instead of a record count
But, later, when that row is selected, if it was a valid sql statement, I then show the results of the sql in a second data table.
My problem is, since the column with the record count is a rendered column, it is not in row().data(). I am looking at what is in row() but not seeing the rendered data. What I was going to do is if the 3rd column does not 'Error with SQL' then I would load that second data table.
ah, i forgot that the data was stored in an array if the sql statement was successful I ended up using that