Using ajax in a callback where the parent process itself relies on an ajax call
up vote
5
down vote
favorite
I'm working with an application that uses DataTables to generate a HTML table which is populated by data from an ajax request.
This is fairly simple:
var substancesTable = $('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url": "/get-substances.json",
"method": "POST",
"cache": false,
"dataSrc": function (json) {
// Update non-Datatables UI elements and perform other functions based on the ajax response
$('#numSubstances').html(json.recordsTotal);
drawOptionsButton(json.isFiltering);
// Must return data for DataTables to work
return json.data;
}
},
// ...
});
There is a callback which DataTables provides, called rowCallback
(https://datatables.net/reference/option/rowCallback) which allows post processing of table rows after the table has been drawn. The key thing here is that it's after the ajax request to /get-substances.json
; the table must be populated with data because this callback is used to manipulate data within it at that point.
Within rowCallback
I'm providing an array of row ID's in my table - that is to say ID's which correspond to <tr>
elements inside #substancesTable
- and I go on to expand these rows. I can do this manually by hardcoding in an array of row ID's, e.g.
var substancesTable = $('#substancesTable').DataTable({
// ...
"rowCallback": function(row) {
var id = $(row).find('td:first').text();
var index = $.inArray(id, ['4', '7']); // hardcoded array
if (index !== -1) {
var tr = $(row).closest('tr');
var row = substancesTable.row( tr );
row.child.show();
tr.addClass('active');
}
});
The array I've hardcoded means rows 4 and 7 are expanded after the table has been populated, which is equivalent to the user clicking on them.
The problem I have is that I don't want to hardcode the array. The application stores the equivalent of var index
in Redis (cache) meaning that we can grab the data easily even if the user leaves the page. So I have added a second ajax request (outside the var substancesTable...
block) to obtain the Redis data. This makes an ajax request to populate an array, activeRows
:
var activeRows = ;
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
activeRows = data;
console.log(activeRows);
});
I understand that the nature of ajax means my code is asynchronous. In some cases the ajax request shown above will complete before the DataTable is drawn, so I get the console.log(activeRows) appearing before the table is rendered, and in other cases it happens afterwards.
What is the correct way to make this second ajax request such that the values from it can be used in place of the hardcoded array? I appreciate I will need to convert the response to an array (since it's still JSON in the console.log
statement). But my question is focused on where to put this code such that it can be used reliably inside rowCallback
?
I have read How do I return the response from an asynchronous call? and understand about the async nature. I can't work out how to structure this to be used in a callback that's already part of an ajax request.
Any advice would be appreciated.
The application uses DataTables version 1.10.16 and jquery 3.2.1
javascript jquery ajax
add a comment |
up vote
5
down vote
favorite
I'm working with an application that uses DataTables to generate a HTML table which is populated by data from an ajax request.
This is fairly simple:
var substancesTable = $('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url": "/get-substances.json",
"method": "POST",
"cache": false,
"dataSrc": function (json) {
// Update non-Datatables UI elements and perform other functions based on the ajax response
$('#numSubstances').html(json.recordsTotal);
drawOptionsButton(json.isFiltering);
// Must return data for DataTables to work
return json.data;
}
},
// ...
});
There is a callback which DataTables provides, called rowCallback
(https://datatables.net/reference/option/rowCallback) which allows post processing of table rows after the table has been drawn. The key thing here is that it's after the ajax request to /get-substances.json
; the table must be populated with data because this callback is used to manipulate data within it at that point.
Within rowCallback
I'm providing an array of row ID's in my table - that is to say ID's which correspond to <tr>
elements inside #substancesTable
- and I go on to expand these rows. I can do this manually by hardcoding in an array of row ID's, e.g.
var substancesTable = $('#substancesTable').DataTable({
// ...
"rowCallback": function(row) {
var id = $(row).find('td:first').text();
var index = $.inArray(id, ['4', '7']); // hardcoded array
if (index !== -1) {
var tr = $(row).closest('tr');
var row = substancesTable.row( tr );
row.child.show();
tr.addClass('active');
}
});
The array I've hardcoded means rows 4 and 7 are expanded after the table has been populated, which is equivalent to the user clicking on them.
The problem I have is that I don't want to hardcode the array. The application stores the equivalent of var index
in Redis (cache) meaning that we can grab the data easily even if the user leaves the page. So I have added a second ajax request (outside the var substancesTable...
block) to obtain the Redis data. This makes an ajax request to populate an array, activeRows
:
var activeRows = ;
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
activeRows = data;
console.log(activeRows);
});
I understand that the nature of ajax means my code is asynchronous. In some cases the ajax request shown above will complete before the DataTable is drawn, so I get the console.log(activeRows) appearing before the table is rendered, and in other cases it happens afterwards.
What is the correct way to make this second ajax request such that the values from it can be used in place of the hardcoded array? I appreciate I will need to convert the response to an array (since it's still JSON in the console.log
statement). But my question is focused on where to put this code such that it can be used reliably inside rowCallback
?
I have read How do I return the response from an asynchronous call? and understand about the async nature. I can't work out how to structure this to be used in a callback that's already part of an ajax request.
Any advice would be appreciated.
The application uses DataTables version 1.10.16 and jquery 3.2.1
javascript jquery ajax
You can call var substancesTable = ... block with in done callback of '/view-substance/get-active-rows' ajax request.
– Chinmoy Samanta
Nov 12 at 10:26
add a comment |
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I'm working with an application that uses DataTables to generate a HTML table which is populated by data from an ajax request.
This is fairly simple:
var substancesTable = $('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url": "/get-substances.json",
"method": "POST",
"cache": false,
"dataSrc": function (json) {
// Update non-Datatables UI elements and perform other functions based on the ajax response
$('#numSubstances').html(json.recordsTotal);
drawOptionsButton(json.isFiltering);
// Must return data for DataTables to work
return json.data;
}
},
// ...
});
There is a callback which DataTables provides, called rowCallback
(https://datatables.net/reference/option/rowCallback) which allows post processing of table rows after the table has been drawn. The key thing here is that it's after the ajax request to /get-substances.json
; the table must be populated with data because this callback is used to manipulate data within it at that point.
Within rowCallback
I'm providing an array of row ID's in my table - that is to say ID's which correspond to <tr>
elements inside #substancesTable
- and I go on to expand these rows. I can do this manually by hardcoding in an array of row ID's, e.g.
var substancesTable = $('#substancesTable').DataTable({
// ...
"rowCallback": function(row) {
var id = $(row).find('td:first').text();
var index = $.inArray(id, ['4', '7']); // hardcoded array
if (index !== -1) {
var tr = $(row).closest('tr');
var row = substancesTable.row( tr );
row.child.show();
tr.addClass('active');
}
});
The array I've hardcoded means rows 4 and 7 are expanded after the table has been populated, which is equivalent to the user clicking on them.
The problem I have is that I don't want to hardcode the array. The application stores the equivalent of var index
in Redis (cache) meaning that we can grab the data easily even if the user leaves the page. So I have added a second ajax request (outside the var substancesTable...
block) to obtain the Redis data. This makes an ajax request to populate an array, activeRows
:
var activeRows = ;
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
activeRows = data;
console.log(activeRows);
});
I understand that the nature of ajax means my code is asynchronous. In some cases the ajax request shown above will complete before the DataTable is drawn, so I get the console.log(activeRows) appearing before the table is rendered, and in other cases it happens afterwards.
What is the correct way to make this second ajax request such that the values from it can be used in place of the hardcoded array? I appreciate I will need to convert the response to an array (since it's still JSON in the console.log
statement). But my question is focused on where to put this code such that it can be used reliably inside rowCallback
?
I have read How do I return the response from an asynchronous call? and understand about the async nature. I can't work out how to structure this to be used in a callback that's already part of an ajax request.
Any advice would be appreciated.
The application uses DataTables version 1.10.16 and jquery 3.2.1
javascript jquery ajax
I'm working with an application that uses DataTables to generate a HTML table which is populated by data from an ajax request.
This is fairly simple:
var substancesTable = $('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url": "/get-substances.json",
"method": "POST",
"cache": false,
"dataSrc": function (json) {
// Update non-Datatables UI elements and perform other functions based on the ajax response
$('#numSubstances').html(json.recordsTotal);
drawOptionsButton(json.isFiltering);
// Must return data for DataTables to work
return json.data;
}
},
// ...
});
There is a callback which DataTables provides, called rowCallback
(https://datatables.net/reference/option/rowCallback) which allows post processing of table rows after the table has been drawn. The key thing here is that it's after the ajax request to /get-substances.json
; the table must be populated with data because this callback is used to manipulate data within it at that point.
Within rowCallback
I'm providing an array of row ID's in my table - that is to say ID's which correspond to <tr>
elements inside #substancesTable
- and I go on to expand these rows. I can do this manually by hardcoding in an array of row ID's, e.g.
var substancesTable = $('#substancesTable').DataTable({
// ...
"rowCallback": function(row) {
var id = $(row).find('td:first').text();
var index = $.inArray(id, ['4', '7']); // hardcoded array
if (index !== -1) {
var tr = $(row).closest('tr');
var row = substancesTable.row( tr );
row.child.show();
tr.addClass('active');
}
});
The array I've hardcoded means rows 4 and 7 are expanded after the table has been populated, which is equivalent to the user clicking on them.
The problem I have is that I don't want to hardcode the array. The application stores the equivalent of var index
in Redis (cache) meaning that we can grab the data easily even if the user leaves the page. So I have added a second ajax request (outside the var substancesTable...
block) to obtain the Redis data. This makes an ajax request to populate an array, activeRows
:
var activeRows = ;
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
activeRows = data;
console.log(activeRows);
});
I understand that the nature of ajax means my code is asynchronous. In some cases the ajax request shown above will complete before the DataTable is drawn, so I get the console.log(activeRows) appearing before the table is rendered, and in other cases it happens afterwards.
What is the correct way to make this second ajax request such that the values from it can be used in place of the hardcoded array? I appreciate I will need to convert the response to an array (since it's still JSON in the console.log
statement). But my question is focused on where to put this code such that it can be used reliably inside rowCallback
?
I have read How do I return the response from an asynchronous call? and understand about the async nature. I can't work out how to structure this to be used in a callback that's already part of an ajax request.
Any advice would be appreciated.
The application uses DataTables version 1.10.16 and jquery 3.2.1
javascript jquery ajax
javascript jquery ajax
edited 2 days ago
asked Nov 8 at 10:47
Andy
2,1491840
2,1491840
You can call var substancesTable = ... block with in done callback of '/view-substance/get-active-rows' ajax request.
– Chinmoy Samanta
Nov 12 at 10:26
add a comment |
You can call var substancesTable = ... block with in done callback of '/view-substance/get-active-rows' ajax request.
– Chinmoy Samanta
Nov 12 at 10:26
You can call var substancesTable = ... block with in done callback of '/view-substance/get-active-rows' ajax request.
– Chinmoy Samanta
Nov 12 at 10:26
You can call var substancesTable = ... block with in done callback of '/view-substance/get-active-rows' ajax request.
– Chinmoy Samanta
Nov 12 at 10:26
add a comment |
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
You can actually use the ajax
option to:
Make the first AJAX request which retrieves the active rows.
Once the active rows are retrieved, make the second AJAX request which retrieves the table data.
Example: (see full code and demo here)
var activeRows = ;
function getActiveRows() {
return $.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(data){
activeRows = data;
console.log(activeRows);
});
}
function getTableData(data, callback) {
return $.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
}
$('#example').dataTable({
ajax: function(data, callback){
getActiveRows().always(function(){
getTableData(data, callback);
});
},
rowCallback: function(row, data){
...
}
});
UPDATE
In the above example, I separated the AJAX calls into two different functions mainly to avoid long indentation in the ajax
option when you call the $('#example').dataTable()
. The code would otherwise look like:
var activeRows = ;
$('#example').dataTable({
ajax: function(data, callback){
// 1. Retrieve the active rows.
$.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(res){
activeRows = res;
console.log(activeRows);
}).always(function(){
// 2. Retrieve the table data.
$.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
});
},
rowCallback: function(row, data){
...
}
});
I used the .always()
so that the table data would still be retrieved in case of failures in retrieving the active rows.
This looks good. Please can you add some information about how it works, particularly the code inside the$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.
– Andy
Nov 13 at 15:17
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to/get-substances.json
. I've updated the original question - see the comment that starts// Update non-Datatables UI elements
. Here I'm writing to a div with the ID#numSubstances
the number of records returned from the JSON data and running another custom function calleddrawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near.done(callback)
but not sure where to go from here. Thanks.
– Andy
2 days ago
.done(callback)
is really a shortcut for.done( function( data ){ callback( data ); } )
. So (I think) you could just add that$('#numSubstances').html(json.recordsTotal);
anddrawOptionsButton(json.isFiltering);
in thatdone
function - after thecallback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
andisFiltering
) just as with theactiveRows
variable - e.g.var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such asdraw
orpreDraw
.
– Sally CJ
2 days ago
add a comment |
up vote
1
down vote
You could solve your problem with Promises. Promises are objects that help you manage and coordinate asynchronous tasks. Your case would look something like this:
var activeRows = ;
var substancesTable = $('#substancesTable').DataTable({
// ...
});
var pDataTable = new Promise(function(resolve, reject){
// you wan't to resolve just once,
// after the table has finished processing the received data.
// (You may want to change draw to an event that's more suitable)
substancesTable.one('draw', resolve);
});
var pOpenRows = new Promise(function( resolve, reject ){
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
// you can either save your rows globaly or give them to the resolve function
// you don't have to do both
activeRows = data;
resolve( data );
});
});
// Here we basically create a third promise, which resolves (or rejects)
// automatically based on the promises in the array.
Promise.all([pDataTable, pOpenRows])
.then(function( values ){
// expand your table rows here
// Note: if you gave your rows to the resolve function you can access
// them here in values[1] (pDataTable's data would be in values[0])
});
In case you want to learn more about Promises:
- https://developers.google.com/web/fundamentals/primers/promises
- https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://scotch.io/tutorials/javascript-promises-for-dummies
For details on browser support you may look here:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise- https://caniuse.com/#search=Promise
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
You can actually use the ajax
option to:
Make the first AJAX request which retrieves the active rows.
Once the active rows are retrieved, make the second AJAX request which retrieves the table data.
Example: (see full code and demo here)
var activeRows = ;
function getActiveRows() {
return $.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(data){
activeRows = data;
console.log(activeRows);
});
}
function getTableData(data, callback) {
return $.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
}
$('#example').dataTable({
ajax: function(data, callback){
getActiveRows().always(function(){
getTableData(data, callback);
});
},
rowCallback: function(row, data){
...
}
});
UPDATE
In the above example, I separated the AJAX calls into two different functions mainly to avoid long indentation in the ajax
option when you call the $('#example').dataTable()
. The code would otherwise look like:
var activeRows = ;
$('#example').dataTable({
ajax: function(data, callback){
// 1. Retrieve the active rows.
$.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(res){
activeRows = res;
console.log(activeRows);
}).always(function(){
// 2. Retrieve the table data.
$.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
});
},
rowCallback: function(row, data){
...
}
});
I used the .always()
so that the table data would still be retrieved in case of failures in retrieving the active rows.
This looks good. Please can you add some information about how it works, particularly the code inside the$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.
– Andy
Nov 13 at 15:17
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to/get-substances.json
. I've updated the original question - see the comment that starts// Update non-Datatables UI elements
. Here I'm writing to a div with the ID#numSubstances
the number of records returned from the JSON data and running another custom function calleddrawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near.done(callback)
but not sure where to go from here. Thanks.
– Andy
2 days ago
.done(callback)
is really a shortcut for.done( function( data ){ callback( data ); } )
. So (I think) you could just add that$('#numSubstances').html(json.recordsTotal);
anddrawOptionsButton(json.isFiltering);
in thatdone
function - after thecallback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
andisFiltering
) just as with theactiveRows
variable - e.g.var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such asdraw
orpreDraw
.
– Sally CJ
2 days ago
add a comment |
up vote
3
down vote
accepted
You can actually use the ajax
option to:
Make the first AJAX request which retrieves the active rows.
Once the active rows are retrieved, make the second AJAX request which retrieves the table data.
Example: (see full code and demo here)
var activeRows = ;
function getActiveRows() {
return $.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(data){
activeRows = data;
console.log(activeRows);
});
}
function getTableData(data, callback) {
return $.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
}
$('#example').dataTable({
ajax: function(data, callback){
getActiveRows().always(function(){
getTableData(data, callback);
});
},
rowCallback: function(row, data){
...
}
});
UPDATE
In the above example, I separated the AJAX calls into two different functions mainly to avoid long indentation in the ajax
option when you call the $('#example').dataTable()
. The code would otherwise look like:
var activeRows = ;
$('#example').dataTable({
ajax: function(data, callback){
// 1. Retrieve the active rows.
$.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(res){
activeRows = res;
console.log(activeRows);
}).always(function(){
// 2. Retrieve the table data.
$.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
});
},
rowCallback: function(row, data){
...
}
});
I used the .always()
so that the table data would still be retrieved in case of failures in retrieving the active rows.
This looks good. Please can you add some information about how it works, particularly the code inside the$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.
– Andy
Nov 13 at 15:17
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to/get-substances.json
. I've updated the original question - see the comment that starts// Update non-Datatables UI elements
. Here I'm writing to a div with the ID#numSubstances
the number of records returned from the JSON data and running another custom function calleddrawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near.done(callback)
but not sure where to go from here. Thanks.
– Andy
2 days ago
.done(callback)
is really a shortcut for.done( function( data ){ callback( data ); } )
. So (I think) you could just add that$('#numSubstances').html(json.recordsTotal);
anddrawOptionsButton(json.isFiltering);
in thatdone
function - after thecallback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
andisFiltering
) just as with theactiveRows
variable - e.g.var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such asdraw
orpreDraw
.
– Sally CJ
2 days ago
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
You can actually use the ajax
option to:
Make the first AJAX request which retrieves the active rows.
Once the active rows are retrieved, make the second AJAX request which retrieves the table data.
Example: (see full code and demo here)
var activeRows = ;
function getActiveRows() {
return $.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(data){
activeRows = data;
console.log(activeRows);
});
}
function getTableData(data, callback) {
return $.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
}
$('#example').dataTable({
ajax: function(data, callback){
getActiveRows().always(function(){
getTableData(data, callback);
});
},
rowCallback: function(row, data){
...
}
});
UPDATE
In the above example, I separated the AJAX calls into two different functions mainly to avoid long indentation in the ajax
option when you call the $('#example').dataTable()
. The code would otherwise look like:
var activeRows = ;
$('#example').dataTable({
ajax: function(data, callback){
// 1. Retrieve the active rows.
$.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(res){
activeRows = res;
console.log(activeRows);
}).always(function(){
// 2. Retrieve the table data.
$.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
});
},
rowCallback: function(row, data){
...
}
});
I used the .always()
so that the table data would still be retrieved in case of failures in retrieving the active rows.
You can actually use the ajax
option to:
Make the first AJAX request which retrieves the active rows.
Once the active rows are retrieved, make the second AJAX request which retrieves the table data.
Example: (see full code and demo here)
var activeRows = ;
function getActiveRows() {
return $.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(data){
activeRows = data;
console.log(activeRows);
});
}
function getTableData(data, callback) {
return $.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
}
$('#example').dataTable({
ajax: function(data, callback){
getActiveRows().always(function(){
getTableData(data, callback);
});
},
rowCallback: function(row, data){
...
}
});
UPDATE
In the above example, I separated the AJAX calls into two different functions mainly to avoid long indentation in the ajax
option when you call the $('#example').dataTable()
. The code would otherwise look like:
var activeRows = ;
$('#example').dataTable({
ajax: function(data, callback){
// 1. Retrieve the active rows.
$.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(res){
activeRows = res;
console.log(activeRows);
}).always(function(){
// 2. Retrieve the table data.
$.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
});
},
rowCallback: function(row, data){
...
}
});
I used the .always()
so that the table data would still be retrieved in case of failures in retrieving the active rows.
edited Nov 13 at 15:56
answered Nov 13 at 14:49
Sally CJ
7,2722416
7,2722416
This looks good. Please can you add some information about how it works, particularly the code inside the$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.
– Andy
Nov 13 at 15:17
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to/get-substances.json
. I've updated the original question - see the comment that starts// Update non-Datatables UI elements
. Here I'm writing to a div with the ID#numSubstances
the number of records returned from the JSON data and running another custom function calleddrawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near.done(callback)
but not sure where to go from here. Thanks.
– Andy
2 days ago
.done(callback)
is really a shortcut for.done( function( data ){ callback( data ); } )
. So (I think) you could just add that$('#numSubstances').html(json.recordsTotal);
anddrawOptionsButton(json.isFiltering);
in thatdone
function - after thecallback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
andisFiltering
) just as with theactiveRows
variable - e.g.var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such asdraw
orpreDraw
.
– Sally CJ
2 days ago
add a comment |
This looks good. Please can you add some information about how it works, particularly the code inside the$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.
– Andy
Nov 13 at 15:17
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to/get-substances.json
. I've updated the original question - see the comment that starts// Update non-Datatables UI elements
. Here I'm writing to a div with the ID#numSubstances
the number of records returned from the JSON data and running another custom function calleddrawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near.done(callback)
but not sure where to go from here. Thanks.
– Andy
2 days ago
.done(callback)
is really a shortcut for.done( function( data ){ callback( data ); } )
. So (I think) you could just add that$('#numSubstances').html(json.recordsTotal);
anddrawOptionsButton(json.isFiltering);
in thatdone
function - after thecallback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
andisFiltering
) just as with theactiveRows
variable - e.g.var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such asdraw
orpreDraw
.
– Sally CJ
2 days ago
This looks good. Please can you add some information about how it works, particularly the code inside the
$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.– Andy
Nov 13 at 15:17
This looks good. Please can you add some information about how it works, particularly the code inside the
$('#example').dataTable({
block which references the other functions? I'm trying to understand the flow of this so I can use the same principles in other parts of my application. Thanks in advance.– Andy
Nov 13 at 15:17
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
I updated the answer.. if you still need clarification, let me know. I've also updated the demo, but it still uses the functions.
– Sally CJ
Nov 13 at 15:46
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to
/get-substances.json
. I've updated the original question - see the comment that starts // Update non-Datatables UI elements
. Here I'm writing to a div with the ID #numSubstances
the number of records returned from the JSON data and running another custom function called drawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near .done(callback)
but not sure where to go from here. Thanks.– Andy
2 days ago
this is brilliant and works really well. Only question is that I was performing some other tasks during the ajax callback to
/get-substances.json
. I've updated the original question - see the comment that starts // Update non-Datatables UI elements
. Here I'm writing to a div with the ID #numSubstances
the number of records returned from the JSON data and running another custom function called drawOptionsButton()
. I don't know where this fits in to the code you've provided. Please can you explain? I guess it's somewhere near .done(callback)
but not sure where to go from here. Thanks.– Andy
2 days ago
.done(callback)
is really a shortcut for .done( function( data ){ callback( data ); } )
. So (I think) you could just add that $('#numSubstances').html(json.recordsTotal);
and drawOptionsButton(json.isFiltering);
in that done
function - after the callback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
and isFiltering
) just as with the activeRows
variable - e.g. var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such as draw
or preDraw
.– Sally CJ
2 days ago
.done(callback)
is really a shortcut for .done( function( data ){ callback( data ); } )
. So (I think) you could just add that $('#numSubstances').html(json.recordsTotal);
and drawOptionsButton(json.isFiltering);
in that done
function - after the callback( data )
part. Alternatively, you can also "save" those two properties (recordsTotal
and isFiltering
) just as with the activeRows
variable - e.g. var activeRows = , recordsTotal = 0, isFiltering;
, and then access/use them from a function hooked to a DataTables event such as draw
or preDraw
.– Sally CJ
2 days ago
add a comment |
up vote
1
down vote
You could solve your problem with Promises. Promises are objects that help you manage and coordinate asynchronous tasks. Your case would look something like this:
var activeRows = ;
var substancesTable = $('#substancesTable').DataTable({
// ...
});
var pDataTable = new Promise(function(resolve, reject){
// you wan't to resolve just once,
// after the table has finished processing the received data.
// (You may want to change draw to an event that's more suitable)
substancesTable.one('draw', resolve);
});
var pOpenRows = new Promise(function( resolve, reject ){
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
// you can either save your rows globaly or give them to the resolve function
// you don't have to do both
activeRows = data;
resolve( data );
});
});
// Here we basically create a third promise, which resolves (or rejects)
// automatically based on the promises in the array.
Promise.all([pDataTable, pOpenRows])
.then(function( values ){
// expand your table rows here
// Note: if you gave your rows to the resolve function you can access
// them here in values[1] (pDataTable's data would be in values[0])
});
In case you want to learn more about Promises:
- https://developers.google.com/web/fundamentals/primers/promises
- https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://scotch.io/tutorials/javascript-promises-for-dummies
For details on browser support you may look here:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise- https://caniuse.com/#search=Promise
add a comment |
up vote
1
down vote
You could solve your problem with Promises. Promises are objects that help you manage and coordinate asynchronous tasks. Your case would look something like this:
var activeRows = ;
var substancesTable = $('#substancesTable').DataTable({
// ...
});
var pDataTable = new Promise(function(resolve, reject){
// you wan't to resolve just once,
// after the table has finished processing the received data.
// (You may want to change draw to an event that's more suitable)
substancesTable.one('draw', resolve);
});
var pOpenRows = new Promise(function( resolve, reject ){
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
// you can either save your rows globaly or give them to the resolve function
// you don't have to do both
activeRows = data;
resolve( data );
});
});
// Here we basically create a third promise, which resolves (or rejects)
// automatically based on the promises in the array.
Promise.all([pDataTable, pOpenRows])
.then(function( values ){
// expand your table rows here
// Note: if you gave your rows to the resolve function you can access
// them here in values[1] (pDataTable's data would be in values[0])
});
In case you want to learn more about Promises:
- https://developers.google.com/web/fundamentals/primers/promises
- https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://scotch.io/tutorials/javascript-promises-for-dummies
For details on browser support you may look here:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise- https://caniuse.com/#search=Promise
add a comment |
up vote
1
down vote
up vote
1
down vote
You could solve your problem with Promises. Promises are objects that help you manage and coordinate asynchronous tasks. Your case would look something like this:
var activeRows = ;
var substancesTable = $('#substancesTable').DataTable({
// ...
});
var pDataTable = new Promise(function(resolve, reject){
// you wan't to resolve just once,
// after the table has finished processing the received data.
// (You may want to change draw to an event that's more suitable)
substancesTable.one('draw', resolve);
});
var pOpenRows = new Promise(function( resolve, reject ){
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
// you can either save your rows globaly or give them to the resolve function
// you don't have to do both
activeRows = data;
resolve( data );
});
});
// Here we basically create a third promise, which resolves (or rejects)
// automatically based on the promises in the array.
Promise.all([pDataTable, pOpenRows])
.then(function( values ){
// expand your table rows here
// Note: if you gave your rows to the resolve function you can access
// them here in values[1] (pDataTable's data would be in values[0])
});
In case you want to learn more about Promises:
- https://developers.google.com/web/fundamentals/primers/promises
- https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://scotch.io/tutorials/javascript-promises-for-dummies
For details on browser support you may look here:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise- https://caniuse.com/#search=Promise
You could solve your problem with Promises. Promises are objects that help you manage and coordinate asynchronous tasks. Your case would look something like this:
var activeRows = ;
var substancesTable = $('#substancesTable').DataTable({
// ...
});
var pDataTable = new Promise(function(resolve, reject){
// you wan't to resolve just once,
// after the table has finished processing the received data.
// (You may want to change draw to an event that's more suitable)
substancesTable.one('draw', resolve);
});
var pOpenRows = new Promise(function( resolve, reject ){
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
// you can either save your rows globaly or give them to the resolve function
// you don't have to do both
activeRows = data;
resolve( data );
});
});
// Here we basically create a third promise, which resolves (or rejects)
// automatically based on the promises in the array.
Promise.all([pDataTable, pOpenRows])
.then(function( values ){
// expand your table rows here
// Note: if you gave your rows to the resolve function you can access
// them here in values[1] (pDataTable's data would be in values[0])
});
In case you want to learn more about Promises:
- https://developers.google.com/web/fundamentals/primers/promises
- https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://scotch.io/tutorials/javascript-promises-for-dummies
For details on browser support you may look here:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise- https://caniuse.com/#search=Promise
answered Nov 12 at 11:23
Fitzi
1387
1387
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206138%2fusing-ajax-in-a-callback-where-the-parent-process-itself-relies-on-an-ajax-call%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can call var substancesTable = ... block with in done callback of '/view-substance/get-active-rows' ajax request.
– Chinmoy Samanta
Nov 12 at 10:26