XMLHttpRequest: need to use success and error functions from ajax - javascript

I have this ajax post function run when an upload button is clicked, the files get uploaded to the server, the server sees for any errors and if there are erros, it notifies the user with the req.end(); function. The problem is, since then, I've moved to XMLHttpRequest() (to use the onprogress functions that it provides) but I still need to use those success and error functions from ajax. Is there a way to use them somehow with XMLHttpRequest? Thank you!
This is the code I have so far:
var xhrVideo = new XMLHttpRequest();
xhrVideo.open('POST', '/uploadVideo', true);
xhrVideo.upload.onprogress = function(e) {
if (e.lengthComputable) {
$('.videoProgress').html(((e.loaded / e.total) * 100).toFixed(0)+'%');
}
};
var videoForm = new FormData($('.videoUploadForm')[0]);
xhrVideo.send(videoForm);
And the ajax code:
var videoData = new FormData($('.videoUploadForm')[0]);
$.ajax({
url: '/uploadVideo',
type: 'POST',
data: videoData,
cache: false,
contentType: false,
processData: false,
mimeType:"multipart/form-data",
success: function(data){
switch(data){
case '1':
alert('Wrong Video File Extension');
break;
case '2':
alert('Wrong Image File Type');
break;
}
},
error: function(data){
alert('Something went wrong! Please reload this page')
}
});

Use listeners for load and error events.
Example adding a listener for success event.
xhrVideo.addEventListener('load', function(e) {
NOTE: the listeners must be added before the send() function
Also, I advise you to read the entire article about using XMLHttpRequest().

Personally , I like to use jquery ajax instead of pure javascript .. so you can use xhr with ajax and catch the progress and load event as well
xhr (default: ActiveXObject when available (IE), the XMLHttpRequest
otherwise) Type: Function() Callback for creating the XMLHttpRequest
object. Defaults to the ActiveXObject when available (IE), the
XMLHttpRequest otherwise. Override to provide your own implementation
for XMLHttpRequest or enhancements to the factory.
in your code you can use it like this
$.ajax({
xhr: function(){
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
//Do something with upload progress
$('.videoProgress').html(Math.round(percentComplete)+"% uploaded");
}
}
}, false);
xhr.upload.addEventListener("load", function(evt){
evt.preventDefault();
},false);
return xhr;
},
// reset of your ajax code

Related

XMLHttpRequest event.loaded behaviour changed?

Some time ago, I wrote a script that looks something like this:
$("#file-upload-button").click(function(e) {
e.preventDefault();
var data = new FormData();
jQuery.each($('#file-upload')[0].files, function(i, file) {
data.append('file', file);
});
$.ajax({
type: "POST",
url: self.urlroot + '/file/upload',
data: data,
contentType: false,
processData: false,
xhr: function() {
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
//more stuff
}
}, false);
//Download progress
xhr.addEventListener("progress", function(evt){
//something similar to above
}, false);
return xhr;
},
success: function( response ) {
//stuff
},
error: function() {
//stuff
}
});
});
And it worked just fine. Today I tried to reuse the code on another page, and I've determined that evt.loaded is no longer tracking how much has been sent to the server, but is instead tracking how much of the file has been loaded into memory to be sent to the server. So it goes to 100% almost immediately, because the file loads to memory very quickly, while not giving an accurate indication of how much has been sent to the server at all. I tried updating my code to something like the following, to no avail:
$("#file-upload-button").change(function(e) {
e.preventDefault();
$("button").attr("disabled", true).fadeTo("fast", 0.5);
var data = new FormData();
jQuery.each($('#file-upload')[0].files, function(i, file) {
data.append('file', file);
});
var xhr = new XMLHttpRequest;
xhr.upload.onprogress = function (evt) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete, evt.loaded, evt.total);
//some stuff
};
xhr.upload.onload = function (e) {
//some stuff
};
xhr.upload.onerror = function (e) {
//some stuff
};
xhr.open("POST", "Owl/");
xhr.send(data);
});
In both instances, it shows evt.loaded to be the same as evt.total almost immediately, and then several seconds later based on the size of the file, the upload actually finishes and the response is processed. Any idea how I can fix this to actually show progress on the upload?

Detect when any ajax calls fail

I have a website where users can work on projects and their work gets automatically saved to my database. Every couple seconds on my site an ajax (post) call occurs (usually in jquery) to check permissions and what not.
With one section of code is there any way so check if any of the ajax calls on your page fail. I don't want to have to go to every individual call and add a block of code to the end.
Basically this is so I can alert the user if they have lost connection or if something is going wrong.
You can use the jQuery event ajaxError. It will be triggered whenever an Ajax request completes with an error:
$(document).ajaxError(function() {
console.error('Error');
});
Check out the documentation.
$(document).ready(function(){
//ajax setup settings
$.ajaxSetup ({
cache: false,
async: false,
statusCode: {
404: function() {
alert('Page not found!');
},
500: function(jqXHR, textStatus) {
alert('Server side: ' + textStatus);
}
}
});
});
I hope this may help you
I would suggest you to override the original jquery ajax function.
var $_ajax = $.ajax; // reference to original ajax
$.ajax = function(options) {
if (options.error) {
// reference to original error callback
var originalErrorHandler = options.error;
var errorHandlerContext = options.context ? options.context : $;
var customErrorHandler = function(xhr, status, error) {
// notify error to your user here
};
// override error callback with custom implementation
options.error = customErrorHandler;
};
return $_ajax.apply($, arguments);
}

XHR progress event not firing until upload completes?

I'm using the following $.ajax command to upload a file from a PhoneGap application:
function updateProgress( evt ) {
if ( evt.lengthComputable ) {
var percentComplete = evt.loaded / evt.total * 100;
console.log( percentComplete + "%" );
}
}
$.ajax({
url: url,
type: "POST",
data: data,
cache: false,
dataType: "json",
processData: false,
contentType: false,
success: successCallback,
error: errorCallback,
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener( "progress", updateProgress, false);
return xhr;
}
});
The upload works fine. However the progress event only fires one time, once the upload has completed. It does not actually fire during uploading - so upload progress does not actually display. There is just a pause while it is uploading, and then it displays 100%.
Any ideas what I am doing wrong?
The upload progress events are fired on xhr.upload, so attach the listener to that rather than xhr. There are also progress events on the xhr object but this is for the response coming back from the server.
See the MDN article for more details.
xhr.upload.addEventListener('progress', updateProgress, false)
(Thanks to A. Wolff and his comment on the OP.)

Why is it so hard to ping my own Server?

I got this piece of cake function:
$.ajax({
url: 'Example.html',
DataType: 'text',
cache: false,
success: function (){
alert ('Yes');
},
error: function (){
alert ('No');
}
});
This function, works just fine, BUT ONLY FOR THE VERY FIRST TIME), from the second time on, the function sends the following error to Chrome:
GET http://MyServer.com/Example.html?_=1406469092100 net::ERR_FAILED
The same situation happens equally with this second JS option:
function doesConnectionExist() {
var xhr = new XMLHttpRequest();
var file = "http://www.example.com/Example.html";
var randomNum = Math.round(Math.random() * 10000);
xhr.open('HEAD', file + "?rand=" + randomNum, false);
try {
xhr.send();
if (xhr.status >= 200 && xhr.status < 304) {
alert ('Yes');
} else {
alert ('No');
}
} catch (e) {
alert ('No');
}
}
1) In the Ajax scenario I just indicate cache: "false"!
2) In the JavaScript scenario I am using random arguments to avoid cache!
Is there anything I am missing? in the Server side??
Please help...
It may be a server problem? I have created a jsFiddle and it seems to work like it should. I wrapped your $.ajax method in a ping function and run it 3 times fetching a jsfiddle resource.
function ping(i) {
$.ajax({
url: '/img/logo.png',
success: function () {
screen.log({text: 'attempt #'+(i+1)+ ' Yes', timed: +i, clear: 'no'});
},
error: function (d){
screen.log({text: 'attempt #'+(i+1)+ ' Nope', timed: +i, clear: 'no'});
}
});
}
See the already mentioned jsFiddle for output
Note: in your second code snippet your supply false as the third paramater to the open method, which means asynchronous = false, so the XHR there is synchronous. The cache: false parameter in the first snippet appends a random reuqeststring to the request. This prevents the browser from caching the fetched resource. I suppose it's not really necessary here.
After hours and hours of try an error I found the Answer....dedicated for those guys who are facing the same problem I did:
In my case this was not a common Web Page, it was an "Offline Web Page" with a Manifest File in it.
Simply in the section "NETWORK" of the manifest file included the file "Example.html" and that's it.
That's all folks!

How to update Ajax call (not content)

Look at this code please - how could I kill / update or restart an ajax call (not content that Ajax calls) after the content has already been called?
I mean the $('#posting_main') is called onclick and animated - how to stop ajax and make it another $('#posting_main') on another click?
$(document).ready(function() {
$("#img_x_ok").click(function(e){
e.preventDefault();
var post_text = $.trim($("#main_text_area").val());
var data_text = 'post_text='+ post_text;
if (post_text === "") return;
var xhr = $.ajax({
type: "POST",
url: "comm_main_post.php",
data: data_text,
cache: false,
success: function (data){
//content
$("#posting_main").fadeIn();
$("#posting_main").load("pull_comm.php");
$("#main_text_area").attr("value", "");
$("#posting_main").animate({
marginTop: "+=130px",
}, 1000 );
}
}); //ajax close
}); }); //both functions close
You can abort the current request with:
xhr.abort();
After having done that, you can run another $.ajax(...) to make a second request.
You could implement it like the following. Note that indenting code makes it a lot more readable!
$(document).ready(function() {
var xhr; // by placing it outside the click handler, you don't create
// a new xhr each time. Rather, you can access the previous xhr
// and overwrite it this way
$("#img_x_ok").click(function(e){
e.preventDefault();
var post_text = $.trim($("#main_text_area").val());
var data_text = 'post_text='+ post_text;
if (post_text === "") return;
if(xhr) xhr.abort(); // abort current xhr if there is one
xhr = $.ajax({
type: "POST",
url: "comm_main_post.php",
data: data_text,
cache: false,
success: function (data){
//content
$("#posting_main").fadeIn();
$("#posting_main").load("pull_comm.php");
$("#main_text_area").attr("value", "");
$("#posting_main").animate({
marginTop: "+=130px",
}, 1000 );
}
});
});
});
I am not sure I fully understand your question, however:
xhr.abort() will kill the AJAX request. After calling abort(), you could modify and resend the request, if desired.
$("#posting_main").stop() will stop the fadeIn animation. (And I think you might need to follow that with $("#posting_main").hide() to be sure it isn't left partially visible.)

Categories