I am trying to send files to my API and want to do it one by one when multiple files are selected and use two different Post calls
In click
event I get the files and loop through them then pass the file data to First()
function call to get back the Unique Id (VersionID
) and pass that VersionID
when making the second call to second()
function.
HTML
<div class="progress">
<div class="progress-bar">0%</div>
</div>
<div id="status"></div>
JQuery
$(function () {
var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
var status = $('#status');
$('#btnUploadFile').on('click', function () {
$("#btnUploadFile").attr("disabled", true);
var files = $("#fileUpload").get(0).files;
var input = document.getElementById('fileUpload');
for (var i = 0; i < input.files.length; ++i) {
var file = input.files[i];
first(9, file.name, (file.size / 1000), file.name.split('.')[1], function (versionID) {
$.when(second(versionID, files[i])).done(function(){
status.html('Uploading ' + i + ' of ' + input.files.length)});
});
};
});
});
First Call
function first(libid, filename, filesize, fileextension, callback) {
var form = new FormData();
form.append("LibId", libid);
form.append("FileName", filename);
form.append("FileSize", filesize);
form.append("FileExtension", fileextension);
var settings = {
"async": false,
"crossDomain": true,
"url": "URL",
"method": "POST",
"processData": false,
"contentType": false,
"mimeType": "multipart/form-data",
"data": form
}
$.ajax(settings).done(function (response) {
callback(response);
});
};
Second call
function second(versionId, fileData) {
var data = new FormData();
data.append('UploadedFiles', fileData);
var bar = $('.progress-bar');
var percent = $('.progress-bar');
$.ajax({
async: true,
crossDomain: true,
url: "URL" + Math.floor(versionId).toString(),
method: "POST",
processData: false,
contentType: false,
mimeType: "multipart/form-data",
data: data,
xhr: function () {
var xhr = $.ajaxSettings.xhr();
xhr.onprogress = function e() {
// For downloads
if (e.lengthComputable) {
console.log(e.loaded / e.total);
}
};
xhr.upload.onprogress = function (e) {
// For uploads
if (e.lengthComputable) {
var percentVal = parseInt((e.loaded / e.total * 100), 10);
console.log("Loaded " + parseInt((e.loaded / e.total * 100), 10) + "%");
var percentValue = percentVal + '%';
bar.width(percentValue);
percent.html(percentValue);
}
};
return xhr;
}
}).done(function (response) {
percent.html("Completed");
}).fail(function (e) {
console.log("failed");
});
};
The issue is $.when(second(versionID, files[i])).done....
does not seem to wait before continuing the loop.
Current Behaviour:
It waits for the
First()
function to finish and then triggersSencond()
function but does not wait forSecond()
function before starting the newFirst()
function.
Expected Behaviour
Wait for the
First()
function to fully finish and then wait for theSecond()
function to fully complete also before looping back to next file and callFirst()
function again.
The other thing I am using async: false
in First()
function and async: true
in Second()
function as if I don't use async: true
in Second()
function, I cant get file upload progress.
Is it possible to wait for second()
function to finish before continuing the loop while using AJAX async: true
?
You have two problems.
First, when
needs to be passed one or more thenable objects, but you are passing undefined
. second
has no return statement. There's no point in using when
though, because you aren't running multiple functions in parallel.
The second problem is that while when
won't call the done
callback until everything you pass to it is done … the for
loop will not wait for the when
to complete.
There are two approaches you can do to solve this problem:
for
loop
var i
first
increment i
first
recursively from second
(until i
is input.files.length
)async
/ await
to manage the promises returned from $.ajax
(which will let you keep the loop).The latter approach will require the use of a transpiler like Babel if you want to support older browsers.
The first approach sounds good, Let me give it a try :) Thanks for the reply