Ajax call is cancelled - javascript

This issue is literally driving me mad and I've already spent hours researching possible solutions :)
My problem is: I've got a script that, upon loading, makes some AJAX calls to the server. This script is a widget and is already configured for cross-domain , etc.
Everything was working fine until now when 1 request has stopped working. The crazy thing is that is only that one, the others work just fine.
You can see in the screenshot below:
This is the code I use to send AJAX requests:
ajax: {
xhr: null,
request: function (url, method, data, success, failure){
if (!this.xhr){
this.xhr = window.ActiveX ? new ActiveXObject("Microsoft.XMLHTTP"): new XMLHttpRequest();
}
var self = this.xhr;
self.onreadystatechange = function () {
if (self.readyState === 4 && self.status === 200){
success(JSON.parse(self.responseText));
} else if (self.readyState === 4) { // something went wrong but complete
if (failure) {
failure();
} else { console.error("Ajax calls has failed."); }
}
};
self.onerror = function() {
if (failure) {
failure();
} else { console.error("Ajax calls has failed."); }
};
this.xhr.open(method,url,true);
this.xhr.setRequestHeader('Content-Type', 'application/json');
this.xhr.send(JSON.stringify(data));
}
}
And this is the call that causes the problem:
this.ajax.request(
this.getWidgetUrl() +"/check_referral_code",
"POST",
{uuid: SL.uuid, ref_code: ref},
function(data) {
if (data.response == "ok") {
// Do something
} else {
console.error(data.message);
}
},
function(data) {
console.error(data.message);
}
);
Can anybody help here?
UPDATE:
The problem seems to be intermittent. If I reload the page it will literally happen 50% of the times

Related

Edge extension: runtime.sendMessage doesn't receive response

I'm writing an Edge extension and struggling with communication between content script and background script.
I'm sending a message from content script to background one:
browser.runtime.sendMessage({ name: "get_card_for_website", url: document.URL }, function(response) {
console.log("Got card for the website:");
console.log(response);
if (response != undefined) {
if (response.card) {
g_card = response.card;
callback(response.card);
}
}
});
Listener in background script is implemented like this:
browser.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.name == 'get_card_for_website') {
get_card_for_website(request.url)
.done(function(element) {
if (element.cards && element.cards.length != 0) {
if (element.cards.length == 1) {
sendResponse({'card': element.cards[0]});
}
else {
get_one_card_for_site(element);
sendResponse({'card': ""});
}
}
});
}
}
Debugger shows message is sent to background script and corresponding code is executed up to sendResponse. But back in content script this callback function is never executed. Console shows no errors.
What could I miss?
Update: I've found out that some tabs receive responses and some don't. I don't really understand difference between first and second ones.
Ok, I figured out the reason of the problem. sendResponse() was called in .done() function, which is called asynchronously. And according to manual:
The sendResponse callback is only valid if used synchronously, or if
the event handler returns true to indicate that it will respond
asynchronously.
So I've modified my background script's function this way:
if (request.name == 'get_card_for_website') {
get_card_for_website(request.url)
.done(function(element) {
if (element.cards && element.cards.length != 0) {
if (element.cards.length == 1) {
sendResponse({'card': element.cards[0]});
}
else {
get_one_card_for_site(element);
sendResponse({'card': ""});
}
}
});
return true; // <----- this part I've added
}
And now it's working like a charm.

why JavaScript form works in Chrome but not in Firefox

i need following function to be execute in Firefox.., but it is working fine in chrome. the problem was when i do 'Inspect Element With Firebug' it is working fine. the method 'EditEncounterBillStatus' is also hitting correctly. but when i don't use 'Inspect Element With Firebug' the method EditEncounterBillStatus is not hitting.. i tried a lot to sort out this. but still i can't can any one help me to find solution thanks in advance.
else if (element.trim() == "Approved") {
var TestPin = prompt("Please Enter your PIN");
if (TestPin != null) {
if (isNaN(TestPin)) {
alert("Please Enter a Valid Pin");
return;
}
else if (TestPin == pin) {
var postVisitData = { VisitId: vid};
$.post("/Emr/WaitingRoom/EditEncounterBillStatus", { VisitId: vid }, function (data) {
});
window.location = "/Emr/Patients/Show?PID=" + pid;
}
else {
alert("Your Entered PIN Is Incorrect");
}
}
else {
return;
}
}
I would recommend doing it like this
else if (TestPin == pin) {
$.post("/Emr/WaitingRoom/EditEncounterBillStatus", { VisitId: vid }, function (data) {
window.location = "/Emr/Patients/Show?PID=" + pid;
});
return; // in case of side effects in unseen code
}
i.e. wait until the $.post has finished before changing the window.location
As the rest of your code is unseen there could be side effects of performing this in this way - hence the return where it is - but even then, not knowing the full call stack there could still be side effects - you have been warned
You should change location upon the success of the post call, so put that in your callback function body:
$.post("/Emr/WaitingRoom/EditEncounterBillStatus", { VisitId: vid },
function (data) {
window.location = "/Emr/Patients/Show?PID=" + pid;
});
This way you are sure you only change location when the post action was executed. Otherwise you risk that you change location before the post happens. In debug mode, and certainly when you step through the code, there is enough time for the post to finish in time, and so your original code then works.

How to handle AJAX errors uniformly in jQuery?

I'd like to detect 401 errors in AJAX calls and redirect to login.html. But I ended up writing many duplicate of code like
if (xhr.status === 401) {
location.assign('/login.html');
}
in the error callback.
My question is, is there a way (the best way?) to handle them uniformly? Could I could inject some code into all of those Ajax calls?
You can use ajaxError() for this. This event triggers when an ajax completed with error. Then you can check the status like this,
$(document).ajaxError(function (event, jqxhr, settings, exception) {
if (jqxhr.status == 401) {
location.assign('/login.html');
}
});
function myAJax(sURL,fnSuccess,fnError) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if(xhttp.status == 200){
fnSuccess(xhttp.responseText);
}else{
fnError('Http Error',xhttp)
}
}
}
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
myAJax('server/url',function(data){
//success code here
},function(){
//error code here
});

Can't get ajaxStop() / ajaxComplete() to work

I have the following JS function:
function getInfo(s,n) {
$.ajax({
type : 'POST',
url : 'includes/stock_summary.php',
timeout : 10000,
data : {
s : s
}
})
.done(function(data) {
function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
alert("Unable to communicate with Yahoo! Finance servers. Please try again later.");
}
return true;
}
$.ajax({
type : 'post',
url : "includes/stock_desc.php",
data : {
s : s
}
})
.done(function(desc) {
$('#desc').html(desc);
})
if(data.change.charAt(0) == '+') {
$('#change').css('color','#090');
$('#puPrc').html('<img src="images/pu_prc_up.png"> ');
}
if(data.change.charAt(0) == '-') {
$('#change').css('color','#D90000');
$('#puPrc').html('<img src="images/pu_prc_dwn.png"> ');
}
var ask = data.ask+" <small>x "+data.askSize+"</small>";
var bid = data.bid+" <small>x "+data.bidSize+"</small>";
var change = data.change+" ("+data.changePc+")";
$('#ask').html(ask);
$('#lt').html(data.lastTrade);
$('#ytd').html(data.ytdReturn);
$('#bid').html(bid);
$('#dayHigh').html(data.dayHigh);
$('#dayLow').html(data.dayLow);
$('#prevClose').html(data.prevClose);
$('#vol').html(data.vol);
$('#yearHigh').html(data.yearHigh);
$('#yearLow').html(data.yearLow);
$('#change').html(change);
$('#stockName').html(n);
$('#sym').html(s.toUpperCase());
$('#open').html(data.sOpen);
})
.fail(function(e) {
alert("Unable to communicate with Yahoo! Finance servers. Please try again later.");
})
$('#chart').html("<img src='http://chart.finance.yahoo.com/z?s="+s+"&t=3m&q=l&l=on&z=m'>");
$('.popUp').bPopup();
}
It is called using onClick().
The function itself does the job correctly but I only want to trigger the line:
$('.popUp').bPopup();
when everything else has finished.
I have used $.ajaxStop(), $(document).ajaxStop(), $.ajaxComplete() and $(document).ajaxComplete()
I have tried them inside, outside, above and below the function but cannot seem to get it to do what I need it to!
The only time it has worked is outside the function but it then runs on page load, which I obviously don't want to happen. I only want it to run when the function completes.
If someone could help me out with this pickle, please help!
If you have just one ajax call you want to add a .always handler that will execute when all the .done and .fail handlers have completed.
.always(function() {
$('.popUp').bPopup();
});
If you have more than one ajax call on your page and you want the code to be fired once all the calls are completed then use the ajaxStop event.
$(function() {
$(document).on('ajaxStop', function() {
$('.popUp').bPopup();
});
});

Ajax callback function behaving randomly. What have i done wrong?

I have following ajax function that behaves randomly. Sometimes alert success finally is displayed. On other occasions, second alert that is
Failure: my status is 500 is displayed.
promptId is passed on from the calling function. I have checked the prompturl and promptId. A valid value
of promptId is displayed on both occasions (success and failure). Also the audio file that I am trying to play is played in both cases (success and failure).
I can not figure out the cause for this random behavior of alerts being displayed.
If 500 error is coming then it means , resource is not found, but my app is able to access the resource(that is playing the audio file).
function ajax_playPrompt(promptId) {
alert(promptId)
var playPromptUrl = soapUrl + "?action=playPrompt&promptId=" + escape(promptId) + "&parentSessionId=" + parentSessionId;
alert(playPromptUrl);
playPrompt_http_request = getNewHttpRequest('text/plain');
playPrompt_http_request.onreadystatechange = callback_ajax_playPrompt;
playPrompt_http_request.open("GET", playPromptUrl, true);
playPrompt_http_request.send(null);
}
function callback_ajax_playPrompt() {
if (playPrompt_http_request.readyState != 4) {
alert("Returning bcause not 4");
return;
}
if (playPrompt_http_request.status == 200) {
alert("Success finally");
}
else {
alert("Failure:My status is "+playPrompt_http_request.status ); // this gives status as 500
}
}
Also to support different browser I am using:
// to provide support for different browsers.
function getNewHttpRequest(contentType) {
var myRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
myRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
myRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
if (myRequest.overrideMimeType) {
myRequest.overrideMimeType(contentType);
}
return myRequest;
}
Additional Info: I have multiple audio files. When I play an audio file the first time, I get the failure alert first time(even though audio is played), but during if I play it again, second time, success alert is displayed.
Can you try this?
function ajax_playPrompt(promptId) {
alert(promptId)
var playPromptUrl = soapUrl + "?action=playPrompt&promptId=" +
escape(promptId) + "&parentSessionId=" + parentSessionId;
alert(playPromptUrl);
var playPrompt_http_request = getNewHttpRequest('text/plain');
playPrompt_http_request.onreadystatechange = function {
if (playPrompt_http_request.readyState != 4) {
alert("Returning bcause not 4");
return;
}
if (playPrompt_http_request.status == 200) {
alert("Success finally");
} else {
alert("Failure:My status is "+playPrompt_http_request.status );
}
};
playPrompt_http_request.open("GET", playPromptUrl, true);
playPrompt_http_request.send(null);
}

Categories