Ajax polling stops to poll after internet disconnect - javascript

I have a sort of ajax polling cycle - pull message, process message, wait, pull again ... - everything works fine until user disconnects from the internet (it can be even so simple user action as sleep/hibernating the PC). After that - at least in latest Chrome - POST fails (logicly) - but after reconnecting to the internet the poll cycle does not get started again (even when the session is still ON).
jQuery(function(){
// ba polling main
function pollingMain() {
$.ajax({
type: "POST",
url: ba_home_url+"/pollingscript.php",
data: {
"load": "something",
"data-one": 0,
"data-two": 0
},
dataType: "json",
timeout: 60000,
success: function(data) {
if( data.status == 'nodata' ){
setTimeout(pollingMain,10000);
} else{
if( data.status == 'okdata' ){
console.log('Ok data recived');
setTimeout(pollingMain,10000);
} else{
//server responded with something we dont know what is
setTimeout(pollingMain,10000);
}
}
},
error: function(request, status, err) {
if(status == "timeout") {
setTimeout(pollingMain,10000);
}
}
});
}
pollingMain();
});
That is my code. I guess I am missing something in the error callback - but what error status handling should I add there ?

You are checking for specific status "timeout". Add else statement for handling other statuses.

Related

AJAX call doesn't go into "error:" block if the API server returns http 500

I want to implement a retry logic in my javascript code. This is how I'm calling the API:
$.ajax({
url: api_url + 'report',
type: 'GET',
dataType: 'json',
async: false,
tryCount : 0,
retryLimit : 3,
headers: {
"Authorization": "Basic " + btoa(api_username + ":" + api_pass)
},
data: {start: start_date, end: end_date},
success: function(result) {
data = result.results;
console.log("success");
},
error : function(xhr, textStatus, errorThrown ) {
console.log("in error");
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
//try again
console.log("try count:");
console.log(this.tryCount);
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
console.log("still 500");
} else {
console.log("still !500");
}
}
});
So when there are issues with the server and it returns http 500 then still my control in the above JS file doesn't go into the "error:" block and this line: "console.log("in error");" doesnt get printed on the console.
How can I correctly implement a retry logic in my code in case my server returns 500 then it should keep on retrying for some x amount of times?
500 error generally means that something is wrong with backend server. So it doesn't get into error block of client JavaScript. I don't think there is anything you can do. But in general you can always ask backend developers to do better error handling and return apt error response if possible.

Ajax return error to call error ajax error call

I have an ajax function which updates my database.. The function works perfectly well and after updating the the database I call the successAlert() function I have created.. however now I want to call the error function in case of error however on testing purposely to break code I still get the successAlert().
Ajax / Javascript:
var share = "test"
var custid = "test"
$.ajax({
url: "assets/ajax/customer-rec.php",
type: "POST",
data: {UpdateAccount: "yes",custid: custid,share: share},
success: function(result){
successAlert()
},
error: function(result){
errorAlert()
}
});
PHP to update Database
if (isset($_POST['UpdateAccount'])){
$custid = $_POST['custid'];
$share = $_POST['share'];
$query="UPDATE `users` SET `share_ord`='$share' WHERE id= $custid";
$stmt = mysql_query($query);
if($stmt === false){
return false
}
}
return false is not an error. If you want to send the error use headers like
header('X-PHP-Response-Code: 404', true, 404);
you can call the same errorAlert() function in success also so that
$.ajax({
url: "assets/ajax/customer-rec.php",
type: "POST",
data: {UpdateAccount: "yes",custid: custid,share: share},
success: function(result){
if(result === false){
errorAlert()
} else {
successAlert()
}
},
error: function(result){
errorAlert()
}
});
To get error you need to return the status code '404' from the php function which is serving your request.
The error callback is fired when the server returns a HTTP status code that indicates an error, as such you should send one, ex HTTP 500
if($stmt === false){
header('HTTP/1.1 500 Server error');
}
See here a list of HTTP status codes
.ajax() will call on success method because, once your request is processed successfully by the server then it reruns HTTP_OK to the client and if .ajax not received HTTP_OK, then it will call error. According to your code, it will call success, because url is exists and server will send HTTP_OK to the browser.
If you want to generate error: then give wrong url or disconnect internet or simply change
In PHP:
if($stmt === false){
//If you want really generate some http error.
header('X-PHP-Response-Code: 500', true, 500);
exit(0);
//or else continue as per code
// return false;
}
In your JS:
$.ajax({
url: "assets/ajax/customer-rec.php",
type: "POST",
data: {UpdateAccount: "yes",custid: custid,share: share},
success: function(result){
if(!result){
showErrorAlert()
} else {
showSuccessAlert()
}
},
error: function(result){
showErrorAlert()
}
});

Using clearTimeout(x) in ajax call

I am writing codes where the code will do some polling for statistics to the server using AJAX. My web application is getting data from the server every 3 seconds once the server returned the data. It is working good but however, I want to apply clearTimeout(x) function to stop the execution and print something to user when any error occur like "timeout" or "error" triggered by error setting. I managed to search the similar case with me here and this also link. But for some reason my code does not do what I want. Here is what I have so far
var timeoutid = 0;
var myfunc = function() {
$.ajax({
type: "POST",
url: "pull.php",
error: function(xhr, status, error){
if( status==="timeout" || status==="error") {
alert("Timeout or unable to receive statistics!");
clearTimeout(timeoutid);
}
},
success: function(msg){
$('#res').val(msg);
//timeoutid = setTimeout(poll, 3000);
},
complete: function(){
timeoutid = setTimeout(myfunc, 3000);
},
timeout: 5000
});
}
myfunc();
The result of the above when I disable my Internet adapter is it keeps looping and alert me the error without stopping the execution. I don't really know how or where do I put my clearTimeout due to localized variable issue based on what I have read. Not really a master in jQuery in detailed though. Appreciate your kind respond and thank you in advance.
It is because you are again creating a new timer in the complete callback which will get executed in the case of error also
var myfunc = function () {
$.ajax({
type: "POST",
url: "pull.php",
error: function (xhr, status, error) {
if (status === "timeout" || status === "error") {
alert("Timeout or unable to receive statistics!");
}
},
success: function (msg) {
$('#res').val(msg);
},
complete: function (jqXHR, status) {
if (status !== "timeout" && status !== "error") {
setTimeout(myfunc, 3000);
}
},
timeout: 5000
});
}
myfunc();

Need xml data to keep POST-ing every 2 seconds until a response is received

This is a very small application for a prototype/experiment. A device is going into sleep every so often to save battery life and a user will access a local webpage and press a button to change something with the device--this sends a POST to the device using the javascript code below.
Since the device can be sleeping when the user presses a button it will miss the POST. I know this is bad practice but I basically need the webpage to keep POST-ing (don't even know if I'm using the terminology correctly) or sending data until it receives the response. I tried a while loop but it only sent it once, maybe I put it in the wrong place.
function execPOST(url, postData, callback) {
var postRequest = newAjaxRequest();
postRequest.onreadystatechange = function() {
if (postRequest.readyState == 4) {
if (postRequest.error) {
callback(1, "Request had an error.");
alert('postRequest Error');
} else {
var status;
try {
status = postRequest.status;
} catch (err) {
callback(1, "Failed to get HTTP status from server.");
return;
}
if (status == 200 || status == 0) {
callback(0, postRequest.responseText);
} else {
callback(1, "POST: Unexpected HTTP Status: "
+ postRequest.status);
alert('POST: Unexpected HTTP Status: '
+ postRequest.status);
}
}
}
}
if (postRequest.overrideMimeType){
postRequest.overrideMimeType("text/xml");
}
postRequest.open("POST", url, false);
//I tried adding this while loop hoping it would keep sending but it only sent once
while (postRequest.readystate != 4)
{
setTimeout('',2000);
postRequest.send(postData);
}
return postRequest;
}
I suggest looking at socket.io to "ping" the device in a loop until it wakes up, THEN send the POST request.
have you considered to use jquery?
function ping () {
$.ajax (
<url>
, {
error: function ( jqXHR, textStatus, errorThrown ) {
}
, timeout: 5000 // in ms
, type: 'POST'
}
}).done(function ( data, textStatus, jqxhr ) {
// whatever
}).fail(function ( jqxhr, textStatus, data ) {
// note that the order of arguments is different from that of the success handler ('done') !
if (textStatus === 'timeout') {
ping();
}
else {
// ... more error handling
}
});
for more info, consult the docs.

Get data as it comes from jquery

I want to display data on a webpage as it comes, let's say I have a tracert on a server and it may take longish time, but I want to show the data as it comes.
If I make it like this:
$.ajax({
url: '/cgi-bin/trace.cgi',
dataType: 'text',
async: true,
cache: false,
success: function (response) {
$('#traceOut').append(response);
}
});
it will only be called when we are done with the cgi request.
I could do it directly with XMLHttpRequest, onreadystatechange and xmlhttp.readyState==3
This works ok in Firefox but in Chrome it only dumps data as it reaches 2k.
How do I do this in jQuery?
It is possible, with polling. The tricky part will be coordinating the process for multiple users on the server side. I'll explain the workflow below.
The Method
/**
* Polls a URL until server indicates task is complete,
* then sends a final request for those results.
*
* Requires jQuery 1.4+.
*/
function poll(params) {
// offer default params
params = $.extend({
error: function(xhr, status, err) {
console.log('Network error: ' + status + ', ' + err);
},
progress: function(prog) {
console.log(prog);
},
timeoutMillis: 600000, // 10 minutes
intervalMillis: 3000 // 3 seconds
}, params);
// kickoff
_poll(params);
function _poll(params) {
$.ajax({
url: params.url,
type: 'GET',
dataType: 'json',
timeout: params.timeoutMillis,
data: 'action=poll',
success: (function(response, status, xhr) {
if ('progress' in response) {
params.progress('Progress: ' + response.progress);
}
if ('status' in response) {
if (response.status == 'pending') {
// slight delay, then poll again
// (non-recursive!)
setTimeout((function() {
_poll(params);
}), params.intervalMillis);
}
else if (response.status == 'cancelled') {
params.progress("Task was cancelled");
}
else {
params.progress("Task complete");
// done polling; get the results
$.ajax({
url: params.url,
type: 'GET',
timeout: params.timeoutMillis,
data: 'action=results',
success: params.success,
error: params.error
});
}
}
}),
error: params.error
});
}
}
Example usage
poll({
url: '/cgi-bin/trace.cgi',
progress: function(prog) {
$('body #progress').text(prog);
},
success: function(response, status, xhr) {
$('body').html(response);
}
});
Workflow
This method will send a request to the server with parameter "action" set to "poll". The CGI script should launch its background task, persist some state in the user session, and respond with JSON-formatted strings:
{"status": "pending", "progress": "0%"}
The browser will repeatedly issue these "action=poll" requests until the response indicates completion. The CGI script must keep track of the task's progress and respond to the browser accordingly. This will involve session handling and concurrency:
{"status": "pending", "progress": "25%"}
{"status": "pending", "progress": "50%"}
{"status": "pending", "progress": "75%"}
{"status": "complete"}
The browser will then issue a "action=results" request to receive the background task's final payload. In this example, it's just HTML:
"<p>The answer is: 42</p>"

Categories

Resources