Reputation: 162
I have tried many different ways to do this.
Like in below code I have tried to run a code after the .each
iteration is completed.
function test(){
var iterate = $.each(ohrArray, function(i, val){
var ohrID = ohrArray[i];
var folderUrl = 'EFMSEmployeeDocumentList' + "/" + locationFolder;
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/Web/GetFolderByServerRelativeUrl('" + folderUrl + "')?$expand=Files";
$.getJSON(url,function(data,status,xhr){
for(var i = 0; i < data.Files.length;i++){
modifiedDate= new Date(data.Files[i].TimeLastModified);
if(documentTitle == ""){
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
countItems++;
}else{
if(documentTitle == data.Files[i].Title)
countItems++;
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
}
}
}
}).complete(function(){
$('#tblCustomListData').dataTable({
paging: true,
searching: true,
bDestroy: true,
"iDisplayLength": 5,
"lengthMenu": [5,10, 25, 50, 100]
});
if(countItems == 0){
alert("No Files Exists");
$("#divCustomListData").hide();
}
});
}
});
$.when(iterate)
.then(function(iterate){
if(countItems == 0){
alert("No Files Exists");
}
});
}
Still while debugging I see that the code of .then
is running before the .each has completed.
What else can we do?
Upvotes: 0
Views: 196
Reputation: 596
iterate
should be a Promise.
When you pass in $.when()
something that's not a Promise it defaults to an already resolved one so the $.then()
is executed immediately.
To use Promises in jQuery check $.Deferred
Then again, you're checking countItems
which gets updated only when each ajax call responds. So what you really need is to ditch .complete()
altogether and have an array of Promises. Each iteration in .each
will create a new Promise in the array and then we'll use $.when()
to check when all the Promises are resolved.
function test(){
var promises = []; //
$.each(ohrArray, function(i, val){
var d = $.Deferred(); // keep the reference to the promise
promises.push(d); // push the promise into the array
var ohrID = ohrArray[i];
var folderUrl = 'EFMSEmployeeDocumentList' + "/" + locationFolder;
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/Web/GetFolderByServerRelativeUrl('" + folderUrl + "')?$expand=Files";
$.getJSON(url,function(data,status,xhr){
for(var i = 0; i < data.Files.length;i++){
modifiedDate= new Date(data.Files[i].TimeLastModified);
if(documentTitle == ""){
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
countItems++;
}else{
if(documentTitle == data.Files[i].Title)
countItems++;
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
}
} // end of for loop
d.resolve(); // the ajax in this iteration has been resolved
}
});
// $.when doesn't accept array of promises by default
$.when.apply(this, promises).then(function(){
// now all the promises have been resolved
// code inside the .complete you had in your question
$('#tblCustomListData').dataTable({
paging: true,
searching: true,
bDestroy: true,
"iDisplayLength": 5,
"lengthMenu": [5,10, 25, 50, 100]
});
if(countItems == 0){
alert("No Files Exists");
$("#divCustomListData").hide();
}
iterate.resolve();
});
}
});
}
I may have misformatted or misplaced some brackets because i didn't run the code.
Upvotes: 2
Reputation: 2147
I've found a solution from dataTable here
$(document).ready(function() {
$('#example').DataTable( {
"ajax": "data/objects.txt",
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" }
]
} );
} );
Otherwise I think you should change your API so you can give the API a list of folderURL
s.
Then you don't need to send a request in every loop of your .each()
.
Further you should be able to create the dataTable
in the success
callback of one and only getJSON
Upvotes: 0
Reputation: 36703
You are make XMLHTTPRequeat inside the $.each
so I suppose you want to execute some code when all the requests are processed. This won't happen directly as JS is async in nature.
You can keep some counter variable to keep track of the total requests processed. Something like this:
var iterate = $.each(ohrArray, function(i, val) {
var url = "......";
var counter = 0;
$.getJSON(url, function(data, status, xhr) {
counter++;
/**** Rest of the code ****/
if (counter == ohrArray.length) {
// Execute the required code by pasting it here or calling a function.
}
});
}
Upvotes: 0