In my page, I call 15 ajax request. Also I have a button which cancels all the pending ajax requests. As per documentation, abort() terminates the request if it has already been sent.
Now when I check my console, even after I click cancel button, I get some replies from ajax script (I guess those were already sent by the time I clicked that button). So how can I make sure no reply should come once I press cancel button?
You can check the script here (couldn't use jsfiddle as not sure how to make ajax request).
JS Code
var xhrPool = [];
$(window).load(function(){
callAjax1();
});
$.ajaxSetup({
beforeSend: function(jqXHR) {
xhrPool.push(jqXHR);
},
complete: function(jqXHR) {
var index = xhrPool.indexOf(jqXHR);
if (index > -1) {
xhrPool.splice(index, 1);
}
}
});
var abortAjax = function () {
$.each(xhrPool, function(idx, jqXHR) {
if(jqXHR && jqXHR .readystate != 4){
jqXHR.abort();
}
});
console.log("All pending cancelled"); // Should not have any ajax return after this point
$.xhrPool = [];
};
$("#cancel-button").click(function (){
abortAjax();
});
function callAjax2(ajaxcallid){
console.log("Initiate ajax call " + ajaxcallid); // Should not have any ajax return after this point
$.ajax({
method: "POST",
url: "test.php"
})
.done(function( msg ) {
console.log(msg + ajaxcallid); // msg = "Ajax return for "
})
.fail(function( jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
});
}
function callAjax1(){
$.ajax({
method: "POST",
url: "test.php"
})
.done(function( msg ) {
for(var i = 0; i < 15; i++){
callAjax2(i);
}
})
.fail(function( jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
});
}
Console Output:
try this
$.each(xhrPool.slice(), function(idx, jqXHR) {
I think while you are aborting, some are returning, so the array gets messed up
this way you are working with a snapshot of the array
though, one or two may still sneak through due to timing of course
Related
This question is a followup of this one. I have created a simple example to check how code is executed within the handler. For the form
<form id="calendar_id" method="post">
Insert date: <input id="date_id" type="text" name="l_date" required>
</form>
I'm trying to retrieve the fields using the following javascript:
function get_form_data_uid($form) {
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function (n, i) {
indexed_array[n['name']] = n['value'];
});
indexed_array['uid'] = 'badbfadbbfi';
return indexed_array;
}
$("#calendar_id").submit(function (e) {
var uri, method, formId, $form, form_data;
// Prevent default submit
e.preventDefault();
e.stopImmediatePropagation();
uri = "/";
method = "POST";
formId = "#calendar_id";
$form = $(formId);
form_data = get_form_data_uid($form);
alert("form_data " + form_data);
// Set-up ajax call
var request = {
url: uri,
type: method,
contentType: "application/json",
accepts: "application/json",
cache: false,
// Setting async to false to give enough time to initialize the local storage with the "token" key
async: false,
dataType: "json",
data: form_data
};
// Make the request
$.ajax(request).done(function (data) { // Handle the response
// Attributes are retrieved as object.attribute_name
console.log("Data from change password from server: " + data);
alert(data.message);
}).fail(function (jqXHR, textStatus, errorThrown) { // Handle failure
console.log(JSON.stringify(jqXHR));
console.log("AJAX error on changing password: " + textStatus + ' : ' + errorThrown);
});
});
However, the code within the handler is not executed (the alert is not shown). Why?
Edit:
The code works jsfiddle but not in firefox.
At least, you are calling a function get_form_data_with_token() which is not defined anywhere in your posted code. Perhaps you meant to call your get_form_data_uid().
Would have just made this a comment, but apparently cannot.
I have a website where I rely on a lot of custom API call. My API return always an XML.
Currently, at the start of each and every $.get or $.post I call, I have this snippet :
var root = $($.parseXML(data)).find("Response");
if (root.children("Type").text() == "Error") {
toastr.error(root.children("Content").text(), "Error " + root.children("ReturnCode").text());
return;
}
However, I feel this code to be much redundant on one of my page, it's used 15 times.
I tried to use the $(document).ajaxSuccess() but the event.stopPropagation don't seem to work here
Is there a way to "intercept" each and every ajax call responses, do some stuff and possibly prevent the call to other defined success functions ?
I assume that you have something like this in many places in your code
$.ajax({
method: "GET",
url: "someurl.html",
dataType: "xml",
success : function() {
var root = $($.parseXML(data)).find("Response");
if (root.children("Type").text() == "Error") {
toastr.error(root.children("Content").text(), "Error " + root.children("ReturnCode").text());
return;
}
// ...
},
error : function(qXHR, textStatus, errorThrown){
toastr.error(errorThrown, "Error " + qXHR.status);
}
});
you could create a generic custom ajax function tha you can re-use
function baseAjaxCall(option, sCb) {
var ajaxOptions = {
method: option.method || "GET",
url: option.url,
dataType: option.dataType || "xml",
success : function(data) {
var root = $($.parseXML(data)).find("Response");
if (root.children("Type").text() == "Error") {
toastr.error(root.children("Content").text(), "Error " + root.children("ReturnCode").text());
return;
}
else {
sCb(root);
}
},
error : function(qXHR, textStatus, errorThrown){
toastr.error(errorThrown, "Error " + qXHR.status);
}
};
//you can check for optional settings
if(option.contentType !== undefined){
ajaxOptions.contentType = option.contentType;
}
$.ajax(ajaxOptions);
}
everywhere in your code you can re-use the baseAjaxCall function
baseAjaxCall({ url: "someurl.html" }, function(root){
// no need to chek for errors here!
});
Hope it's helps!
This question already has answers here:
What's the best way to retry an AJAX request on failure using jQuery?
(9 answers)
Closed 8 years ago.
I am having an ajax call that needs to run and if it fails then it should reinitialze the same ajax. As i have gone through some post there is failure function under where we can tell user that ajax call failed and follow some set of function.
But i wish to reintialiaze the same ajax call in failure or somewhere else so that when that ajax fails so in fails it intilized again.
deleteImage : function(objId,thumburl,original,ev){
jQuery('#imageBlocksDiv').append(jQuery("#confirmboxtmp").html());
setToCenterOfParent( $('#confirmbox'), document.body, false, true );
jQuery("#confirmbox").fadeIn().css({top:-210,position:'fixed'}).animate({top:50}, 100, function() {});
jQuery('#deleteconfirmbox').click(function(){
jQuery(this).text('Deleting..');
if(typeof objId!='undefined'){
var iputadatatologdelete = {
"media_image_objectId": objId,
"action" : "deleted"
};
iputadatatologdelete.company_objectId = jQuery('#cid').val();
iputadatatologdelete.edited_by_user_objectId = jQuery('#uid').val();
var inputData = {
'id' : objId,
'imgurl' : original,
'thumburl' : thumburl
}
jQuery.ajax({
'type':'POST',
'url': '#####/a###pi/###/####/#####',
'data' : inputData,
success : function(response){ //console.log(response)
jQuery('#'+objId).parents().eq(2).remove();
console.log(objId);
jQuery('#confirmbox').hide();
jQuery('#deleteconfirmbox').text('Delete');
pinterest(undefined);
logdata("sc_media_image_edited_log", iputadatatologdelete)
}
});
}
The function is something like this if i go to make function for every kind of ajax that i am calling then that will be bunch of codes. As i have already made loads of ajax with diffrent urls and type.
error : function(xhr, textStatus, errorThrown ) {
//try again
$.ajax(this);
return;
}
Will this work in case of reinitializing the same query.
You can do something like this:
function doAjax() {
$.ajax({
url: ...
success: ...
error: doAjax
});
}
doAjax();
Note, that in case of continuous failure, this will infinitely loop unless you implement a protection mechanism (e.g. a counter and a condition to stop the loop after a number of failed attampts).
To call exactly the same ajax, you can make it recursively, something like this:
function callAjax(){
$.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function() {
callAjax();
})
.always(function() {
alert( "complete" );
});
}
Otherwise you can control it with a "control variable", like this:
function callAjax(){
var control = 0;
while (control === 0){
$.ajax( "example.php" )
.done(function() {
alert( "success" );
control = 1;
})
.fail(function() {
alert( "fail" );
})
.always(function() {
alert( "complete" );
});
}
}
I hope it helps you.
In error callback , call the the same ajax request method
Try below code:
$(document).ready(function(){
(function callAjax(){
$.ajax({
url: url,
success: function(res){ },
complete: callAjax
});
})();
})
You can use "complete" function for that because you either get success or error complete function will call in each case.. http://api.jquery.com/jquery.ajax/
As in the failure function we can reset the same ajax call by below lines .
error : function(xhr, textStatus, errorThrown ) {
jQuery.ajax(this);
return;
},
If i am some where wrong please give the feedbacks on the same
I have a web app.
It is written in asp.net, javascript and jquery.
I have a timer on the page. It will 'ping' my server every 100ms (I know this is not guarantted due to the nature of timers in javascript).
So, this is my code:
function GetImageStatus() {
var val = url + '/Mobile/isNewFrame.ashx?Alias=' + Alias + '&CamIndex=' + camIndex + '&Version=' + version + '&GuidLogOn=' + guidLogOn;
jQuery.get(val)
.success(function (data) {
//invalid session
if (data == '-2') {
document.location.reload(true);
}
else {
//do something useful
}
})
.error(function (jqXHR, textStatus, errorThrown) {
var ct = XMLHttpRequest.errorThrown;
$("#divVersion").html(ct);
});
}
function Start()
{
if (timer4x4) window.clearTimeout(timer4x4);
timer4x4 = window.setTimeout(GetImageStatus, tmrInterval);
}
var timer4x4;
var tmrInterval = 100;
So, my question is this. If the ping/get call takes longer than my tmrInterval is the call aborted before the next call is initiated?
No. I suggest using jQuery ajax with timeout option such as :
$.ajax({
url: val,
type: 'GET',
timeout: tmrInterval,
success: function (data) {
//invalid session
if (data == '-2') {
document.location.reload(true);
}
else {
//do something useful
}
},
error: function (jqXHR, textStatus, errorThrown) {
var ct = XMLHttpRequest.errorThrown;
$("#divVersion").html(ct);
}
});
I use this code, which was taken by another post of stackoverflow, but one part was not working for me.
<script>
// variable to hold request
var request;
// bind to the submit event of our form
$("#notification").submit(function(event){
// prevent default posting of form
event.preventDefault();
// abort any pending request
if (request) {
request.abort();
}
// let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");
// let's disable the inputs for the duration of the ajax request
$inputs.prop("disabled", true);
//this code was added by me cause i saw that when i pass as data {notTitle:"smth"}
//it works, so i wanted to remake that structure and include all my elements.
// Apparently it does not work, maybe because i create a string and by
//{notTitle:"smth"}, notTitle is not passed as string.
x=$("form").serializeArray();
var str="{";
var size = x.length;
$.each(x, function(i, field){
if (field.value!="")
str = str.concat(field.name + ":" + field.value);
else
str = str.concat(field.name + ":" + "k");
if(i!=size-1)
str=str.concat(",");
});
str=str.concat("}");
// fire off the request to /form.php
request = $.ajax({
url: "test.php",
type: "POST",
dataType: 'json',
data: str//{notTitle:"s",notType:''}
});
// callback handler that will be called on success
request.done(function (response, textStatus, jqXHR){
alert(response.status);
});
// callback handler that will be called on failure
request.fail(function (jqXHR, textStatus, errorThrown){
// log the error to the console
alert(
"The following error occured: "+
textStatus, errorThrown
);
});
// callback handler that will be called regardless
// if the request failed or succeeded
request.always(function () {
// reenable the inputs
$inputs.prop("disabled", false);
});
});
</script>
And here is my php
<?php $result = array("status" => "1", "a" => "2");
$notificationTitle = htmlspecialchars($_POST["notTitle"],ENT_QUOTES,'ISO-8859-1');
echo json_encode($result); ?>
Before you suggest the use of serializing the form, I tried it and it does not work. What I noticed is that when I try to pass data to my php file, I cannot read them through $_POST['name of element']. So if I comment the second line of the php file and pass as data {notTitle:'s'} it works and I see the successful message.