How can I wait in an for Loop till an upload is completed and then continue the for Loop with the next number?
I have searched the Internet but there is only the setTimeout function and so on!
Here My code:
for(var f=0;f<4;f++){
var formdata = new FormData();
var id = f+1;
var file = _("filestyle-"+id).files[0];
formdata.append("file"+id, file);
var title = _("title"+id).value;
formdata.append("title"+id, title);
document.getElementById("uploadname").innerHTML=title+"is uploading<br>";
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "../swupload.php");
ajax.send(formdata);
}
in the completeHandler a variable is set to 1
You can set code you want to execute at different stages of ajax request as:-
readyState Holds the status of the XMLHttpRequest. Changes from 0 to 4:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
However in your case you want to execute code after completion of upload, it may be achieve like that:
ajax.onreadystatechange=function()
{
if (ajax.readyState==4 && ajax.status==200)
{
// code to execute after upload
}
}
Ajax is asynchronous, so you can't expect your other synchronous code to wait for it. What you can do is replace your loop with a function, and recall it from your completeHandler callback.
post(1);
function post(id) {
var formdata = new FormData();
var file = _("filestyle-"+id).files[0];
formdata.append("file"+id, file);
var title = _("title"+id).value;
formdata.append("title"+id, title);
document.getElementById("uploadname").innerHTML=title+"is uploading<br>";
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "../swupload.php");
ajax.send(formdata);
function completeHandler() {
if (id < 5) post(id + 1);
}
}
If completeHandler must be defined outside of this function, you can preserve the id with a closure:
ajax.addEventListener("load", completeHandler(id), false);
function completeHandler(id) {
return function() {
if (id < 5) post(id + 1);
}
}
Related
It is my AJAX call with setTimeout
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
document.getElementById('mainContent').style.display = 'none';
if (this.readyState == 4 && this.status == 200) {
xhttp.onload = function(){
document.getElementById("mainContent").innerHTML = this.responseText;
setTimeout(function(
document.getElementById("mainContent").style.display = 'block';
),1000);
}
}
};
xhttp.open("POST", "system.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("lang="+lang);
I want detect when ajax is fully loaded and I have also solution here
I have solution here but I can't understand how it work.
var oldOpen = XMLHttpRequest.prototype.open;
function onStateChange(event) {
// fires on every readystatechange ever
// use `this` to determine which XHR object fired the change event
}
XMLHttpRequest.prototype.open = function() {
// when an XHR object is opened, add a listener for its readystatechange events
this.addEventListener("readystatechange", onStateChange)
// run the real `open`
oldOpen.apply(this, arguments);
}
Can you example me how it work or write full code how it work ?
Since most topics about this subject are over a year old, I asked myself if there are any good solutions to track an ajax progress event from an http service (for a loading bar or to track how many bytes it has downloaded). Without the use of 3rd parties :)
these events:
var ajax = new XMLHttpRequest();
ajax.addEventListener("progress")
ajax.addEventListener("load")
ajax.addEventListener("error")
ajax.addEventListener("abort")
I've made something like that using a promise with notify for the progress :
var deferred = $q.defer();
var fd = new FormData();
fd.append("Filename", file.name);
fd.append("file", file);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function (event) {
deferred.notify(event);
}, false);
xhr.addEventListener("load", function (data) {
deferred.resolve(event.target.response);
}, false);
xhr.addEventListener("error", function (data) {
deferred.reject(event.target.response);
}, false);
xhr.addEventListener("abort", function (data) {
deferred.reject(event.target.response);
}, false);
xhr.open("POST", URL);
xhr.send(fd);
return deferred.promise;
I have two functions here, the first one is triggered by a button and it is meant to trigger a second function which will change the inner html of that first buttons accompanying html area.
My problem is how to pass the arguments from the first function INTO the second one to the button and textfield have the same idnumber.
function doLoad(idnumber, id) {
var file = _(id).files[0];
_("Btn1_QP_"+idnumber).style.display = "none";
_("Display_QP_"+idnumber).innerHTML = "Image uploading......";
var formdata = new FormData();
formdata.append("stPic", file);
var ajax = new XMLHttpRequest();
ajax.addEventListener("load", completeHandler, false);
ajax.open("POST", "pho_stem3.php");
ajax.send(formdata);
}
function completeHandler(event) {
_("Display_QP").innerHTML = 'wahooo';
}
}
In function doLoad idnumber is given by the button and used to identify the proper button with("Btn1_QP_"+idnumber)
how can i achieve this same selective ability in the second function completeHandler in the event listener.
I have tried
ajax.addEventListener("load", completeHandler(idnumber), false);
ajax.addEventListener("load", ("completeHandler"+idnumber), false);
both dont work. how can i preserve and transmit the original argument from doLoad...
You can pass the same id number in response of ajax like this:
function doLoad(idnumber, id) {
var file = _(id).files[0];
_("Btn1_QP_" + idnumber).style.display = "none";
_("Display_QP_" + idnumber).innerHTML = "Image uploading......";
var formdata = new FormData();
formdata.append("stPic", file);
var ajax = new XMLHttpRequest();
ajax.open("POST", "pho_stem3.php");
ajax.send(formdata);
ajax.onreadystatechange = function() {
if (ajax.readyState == 4) {
completeHandler(idnumber);
}
}
}
function completeHandler(idnumber) {
_("Display_QP_" + idnumber).innerHTM = 'wahooo';
}
I am uploading a file via ajax request, by simply splitting them in to chunks.
The problem is progress event, Firefox for some reason doesn't want to fire that event, here is my code (most of the unnecessary code is removed)
//slice file
if(file.mozSlice){
chunk = file.mozSlice(startByte, endByte);
}else if(file.slice){
chunk = file.slice(startByte, endByte);
}else{
chunk = file;
isLast = true;
}
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function(e){
console.log('progress');
}, false);
xhr.upload.addEventListener('error', function(e){
console.log("upload error!");
});
xhr.onreadystatechange = function(e){
if(this.readyState == 4 && this.status == 200){
//this chunk has bee uploaded, proceed with the next one...
}
}
xhr.open('POST', "", true);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');//header
xhr.setRequestHeader('Content-Type', 'application/octet-stream');//generic stream header
xhr.send(chunk);
I'm sure i haven't made any big mistakes since chrome works without any problems, so there must be some Firefox related issue.
for Chrome:
xhr.upload.addEventListener('progress', function(e) {
console.log('progress');
}, false);
for Firefox:
xhr.addEventListener('progress', function(e) {
console.log('progress');
}, false);
I checked my implementation I'm adding the progress event after I call xhr.open, maybe that fixes it?
Try the 2nd code sample here: https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress does that work?
I'm using FormData to ajax a file upload. The upload works, but the problem is that the "error" callback is never invoked. Even when my HTTP response is a 500 internal server error (to test this I tweak server to respond with 500), the "load" callback is invoked.
function upload_image() {
var form = document.getElementById('upload_image_form');
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(e) {
alert("Success callback");
}, false);
xhr.addEventListener("error", function(e) {
alert("Error callback");
}, false);
xhr.open("POST", "/upload_image");
xhr.send(formData);
}
Any ideas? I'm testing this on Chrome.
This setup should work better for your needs:
var req = new XMLHttpRequest();
req.open('POST', '/upload_image');
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if(req.status == 200)
alert(req.responseText);
else
alert("Error loading page\n");
}
};
req.send(formData);
In your code error callback is never called because it is only triggered by network-level errors, it ignores HTTP return codes.
The load event is called whenever the server responds with a message. The semantics of the response don't matter; what's important is that the server responded (in this case with a 500 status). If you wish to apply error semantics to the event, you have to process the status yourself.
Expanding on #rich remer's answer, here's how you could access the status yourself:
function upload_image() {
var form = document.getElementById('upload_image_form');
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(e) {
if(e.currentTarget.status < 400)
alert("Load callback - success!");
else
alert("Load callback - error!");
}, false);
xhr.addEventListener("error", function(e) {
alert("Error callback");
}, false);
xhr.open("POST", "/upload_image");
xhr.send(formData);
}
Please note accessing of the e.currentTarget.status property of the response event (e). Looks like the status is actually available via any of e.{currentTarget,target,srcElement}.status - I'm not sure which one should be used as the best practice, though.
function get(url) {
return new Promise(function(succeed, fail) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.addEventListener("load", function() {
if (req.status < 400)
succeed(req.responseText);
else
fail(new Error("Request failed: " + req.statusText));
});
req.addEventListener("error", function() {
fail(new Error("Network error"));
});
req.send(null);
});
}
code from EJS
by the example code
it is clear that network error has no response, it trigger error event.
response trigger load event
and you have to decide what to do with the response status