I have the following part of a jQuery .ajax call. It checks every second I believe. How can I get to stop after 10 tries?
success: function (data) {
if (!data) {
setTimeout(function (inputInner) { CallIsDataReady(inputInner); }, 1000);
}
EDIT: I implemented one solution but the logging for the service call seems to stop after 2 times.
function CallIsDataReady(input) {
var timer;
var count = 0;
$.ajax({
url: "http://www.example.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
// dataType: "json",
success: function (data) {
if (!data) {
setTimeout(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
}
else {
console.log("data returned - calling callUpDateGrid");
//Continue as data is ready
callUpdateGrid(input);
}
},
error: function (jqXHR, textStatus, errThrown) {
console.log("AJAX call failed in CallIsDataReady");
console.log(errThrown);
}
});
Just assign your setTimeout to a variable, and use a counter, when it reaches 10, call clearTimeout()
user setInterval with a counter:
if (!data) {
var count = 0;
var interval;
interval = setInterval(function (inputInner) {
if (count === 10) {
clearInterval(interval);
return;
}
CallIsDataReady(inputInner);
count++;
}, 1000);
}
// global variable - should be outside your ajax function
var timer;
var count = 0;
....
success : function( data) {
if( ! data ) {
// don't know where you are getting inputInner. assuming its a global variable
timer = setInterval ( function ( inputInner ) {
CallIsDataReady(inputInner);
count++;
if ( count == 10 ) {
clearInterval(timer);
count = 0;
}
}, 1000);
}
}
Use an interval
var count = 0,
handler = setInterval(dostuff, 1000);
function dostuff(inputInner){
//CallIsDataReady(inputInner);
if(++count === 10)
clearInterval(handler);
}
http://jsfiddle.net/mGgLz/
However, you should never rely on the assumption that the ajax call always takes < 1000ms. Check the readyState on the XHR and make sure it's 4 before polling again.
Related
i have a script that reload the page when the value is >= 100 the problem is that location.reload(true); are not working in ie11, i also have tried with window.location = self.location.href; but i am having the same problem, in other browsers it works good.
$(function () {
if (value < 100) {
var timer = setInterval(function () {
$.ajax({
type: "GET",
url: $("#ancUrl").attr('href'),
data: {},
success: function (msg) {
console.log("This is msg:" + msg);
var msgInt = parseInt(msg);
if (msgInt > value)
value = msgInt;
},
error: function (err) {
console.log(err.responseText);
},
dataType: "json"
});
$("#progress-bar").width(value.toString() + "%");
if (value >= 100) {
clearInterval(timer);
window.location = self.location.href;
}
}, 2000);
}
});
You don't appear to have defined self anywhere, so you may have an error there. Beyond that, you're trying to assign the value of href as the whole value of location - which is meant to be an object. Instead, try:
window.location.href = window.location.href;
Try to move the if statement into the success callback.
Like that you can clear the interval into the same stack and reload the page on the good
.
$(function() {
if (value < 100) {
var timer = setInterval(function() {
$.ajax({
type: "GET",
url: $("#ancUrl").attr('href'),
data: {},
success: function(msg) {
console.log("This is msg:" + msg);
var msgInt = parseInt(msg);
if (msgInt > value)
value = msgInt;
$("#progress-bar").width(value.toString() + "%");
if (value >= 100) {
clearInterval(timer);
window.location = self.location.href;
}
},
error: function(err) {
clearInterval(timer);
console.log(err.responseText);
},
dataType: "json"
});
}, 2000);
}
});
place the if in the success function, ajax is asynchronous the if will execute immediately but value will change after the ajax has completed so the code may never reach the if statement
$(function () {
if (value < 100) {
var timer = setInterval(function () {
$.ajax({
type: "GET",
url: $("#ancUrl").attr('href'),
data: {},
success: function (msg) {
console.log("This is msg:" + msg);
var msgInt = parseInt(msg);
if (msgInt > value) {
value = msgInt;
$("#progress-bar").width(value.toString() + "%");
if (value >= 100) {
clearInterval(timer);
location.reload(true);
}
}
},
error: function (err) {
console.log(err.responseText);
},
dataType: "json"
});
}, 2000);
}
});
I am trying to stop my Timeout when I received data back from my ajax post. However, I get the data back, it updates my html, but the timer is still going. What's going wrong?
function getResponse() {
var i = 0;
var reply = null;
var myTimer;
while (i < 24 && reply == null) {
(function(i) {
myTimer = setTimeout(function() {
$.ajax({
url: '/getResponse',
data: "123456",
type: 'POST',
success: function (data) {
console.log("HERE data2 " + data);
if(data != "" || data != null){
reply = data;
document.getElementById("responseText").innerHTML = reply;
clearTimeout(myTimer);
}
},
error: function (error) {
document.getElementById("responseText").innerHTML = error;
console.log(error);
}
});
}, 5000 * i)
})(i++)
}
Here you are overwriting your global myTimer variable in each iteration of the while loop. So every time you are doing clearTimeout(myTimer) you are just clearing the timeout of the last setTimeout that is run when i becomes 23 and not for setTimeout created in the previous 22 iterations of the while loop. You actually have to declare the myTimer variable inside the IIFE in the while loop like the following to clearTimeout for all the 23 setTimeouts created during the while loop:
function getResponse() {
var i = 0;
var reply = null;
// var myTimer;
while (i < 24 && reply == null) {
(function(i) {
var myTimer = setTimeout(function() { // Declare myTimer here
$.ajax({
url: '/getResponse',
data: "123456",
type: 'POST',
success: function (data) {
console.log("HERE data2 " + data);
if(data != "" || data != null){
reply = data;
document.getElementById("responseText").innerHTML = reply;
clearTimeout(myTimer);
}
},
error: function (error) {
document.getElementById("responseText").innerHTML = error;
console.log(error);
}
});
}, 5000 * i)
})(i++)
}
It is cleared. But you are calling your function over and over (23 times) and every time you are setting new timeout and clearing him again.
I'm having problems with a function firing multiple times on click. Specifically, in the below code, the userloggedin(); function fires multiple times when clicked. Typically, it fires once the first time, 3 times the next time and 6 the next.
var timer = null;
function sessCountdown() {
var sec = 120;
timer = setInterval(function() {
sec--;
if (sec >= 0) {
span = document.getElementById("count");
span.innerHTML = sec;
}
}, 1000);
}
function getUserInfo() {
var getUserInfo = $.ajax({
type: 'Get',
url: Config.engineUrl + '?AUserSessionInfo',
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true
});
getUserInfo.done(function(data, jqXHR) {
var sessionModal = $('#session-modal');
if (data.TimeLeft > 0 && data.TimeLeft <= 2 && !sessionModal.hasClass('in')) {
sessionModal.modal('show');
sessCountdown();
} else if (data.TimeLeft === 0){
$('.logout').trigger('click');
}
sessionModal.on('shown.bs.modal', function(e) {
$('#btnSession').on('click', function() {
clearInterval(timer);
userLoggedin();
});
});
});
}
//Check for session info every 60 seconds
setInterval(getUserInfo, 60000);
I appreciate any tips for resolving this that you can provide. Thanks.
Updated Code - With Resolution
var timer = null;
function sessCountdown() {
var sec = 120;
timer = setInterval(function() {
sec--;
if (sec >= 0) {
span = document.getElementById("count");
span.innerHTML = sec;
}
}, 1000);
}
function getUserInfo() {
var sessionModal = $('#session-modal'),
getUserInfo = $.ajax({
type: 'Get',
url: Config.engineUrl + '?AUserSessionInfo',
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true
});
getUserInfo.done(function(data, jqXHR) {
if (data.TimeLeft > 0 && data.TimeLeft <= 2 && !sessionModal.hasClass('in')) {
sessionModal.modal('show');
sessCountdown();
} else if (data.TimeLeft === 0) {
$('.logout').trigger('click');
}
});
}
$('#btnSession').on('click', function() {
clearInterval(timer);
userLoggedin();
});
//Check for session info every 60 seconds
setInterval(getUserInfo, 60000);
i have a JavaScript/jQuery code function that is supposed to call itself up to ten times if there is no data available (determined by web service call). I have implemented the code but the logging inside the web service call indicates that it is called only 1 or 2 times. What is the error in this code?
function CallIsDataReady(input) {
var timer;
var count = 0;
$.ajax({
url: "https://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
success: function (data) {
if (!data) {
setTimeout(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
} else {
console.log("data returned - returning true");
//Continue as data is ready
var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
GetDataFromServer(0, tableView.get_pageSize());
}
},
error: function (jqXHR, textStatus, errThrown) {
console.log("AJAX call failed in CallIsDataReady");
console.log(errThrown);
}
});
}
EDIT: It should try up to ten times and then quit, not go on to the GetDataFromServer. It should return an error. How can I do that?
setTimeout is meant to trigger a function call once, and only once.
Repeat call to setTimeout from within your timeouted callback if you want this to work:
function CallIsDataReady(input) {
var timer;
var count = 0;
function callWebService(){
console.log('calling webservice');
$.ajax({
url: "https://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
success: function (data) {
console.log('count = ' + count);
console.log('data = ' + data);
if (!data){
if(count < 10) {
count++;
setTimeout(callWebService, 1000);
} else {
count = 0;
}
}else{
console.log("data returned - returning true");
//Continue as data is ready
var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
GetDataFromServer(0, tableView.get_pageSize());
}
},
error: function (jqXHR, textStatus, errThrown) {
console.log("AJAX call failed in CallIsDataReady");
console.log(errThrown);
}
});
};
callWebService();
}
count is being reset every time CallIsDataReady is called.
Replace:
function CallIsDataReady(input) {
var timer;
var count = 0;
With:
var count = 0;
function CallIsDataReady(input) { // You won't need the `timer` variable
This will set count to 0 before the first call of CallIsDataReady. Then, each call, the count will be incremented.
Now, to handle that counter properly, replace:
if (!data) {
setTimeout(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
With:
if (!data && count !== 10) {
setTimeout(function(input) {
CallIsDataReady(input);
count++;
}, 1000);
Now, I'm not sure what inputInner is supposed to be, so I replaced that with input. If you want a different variable to be passed to subsequent calls, you'll have to assign a value to inputInner.
In addition to making timer and count into global variables, I think you need to assign a value to inputInner when you execute it:
if (!data) {
setTimeout(function() {
function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}(input);
}, 1000);
}
It looks like you are trying to use setTimeout instead of setInterval. setTimeout calls function only once after certain amount of time. setInterval will be calling your function in intervals until you call clearInterval.
http://www.w3schools.com/jsref/met_win_setinterval.asp
timer= setInterval(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
I'm having hard time figuring how to avoid duplicate ajax call for my infinite scroll javascript code.
It mostly works but sometimes i have 2 or 3 times the same ajax page call causing a sort of loop.
How to avoid this?
Thanks
//infiniteScroll
var currentPage = 1;
var intervalID = -1000;
var scroll = false;
$('document').ready(function(){
if ( scroll == true) {
if (window.location.pathname == "/" && window.location.search == "" && $('#items_container').length > 0) {
$('.pagination').hide();
intervalID = setInterval(checkScroll, 300);
}
};
})
function checkScroll() {
if (nearBottomOfPage()) {
currentPage++;
jQuery.ajax('?page=' + currentPage, {asynchronous:true, evalScripts:true, method:'get',
beforeSend: function(){
var scroll = false;
$('.spinner').show();
},
success: function(data, textStatus, jqXHR) {
$('.spinner').hide();
$('#items_container').append(jQuery(data).find('#items_container').html());
var scroll = true;
if(typeof jQuery(data).find('.item').html() == 'undefined' || jQuery(data).find('.item').html().trim().length == 0 || currentPage == 10){
clearInterval(intervalID);
}
},});
}
}
}
function nearBottomOfPage() {
return scrollDistanceFromBottom() < 450;
}
function scrollDistanceFromBottom(argument) {
return pageHeight() - (window.pageYOffset + self.innerHeight);
}
function pageHeight() {
return Math.max(document.body.scrollHeight, document.body.offsetHeight);
}
It looks like the checkScroll function is being called every 300 milliseconds, and it's possible that an AJAX request will take longer than that.
I see you've got the scroll variable, but you are only checking the value of it on the initial document load, which won't affect the timer.
I would suggest having a look at listening to the scroll event instead of creating a timer: jQuery docs. You could then do something like the following to prevent two ajax calls running:
var ajaxRunning = false;
function checkScroll() {
if (!ajaxRunning && nearBottomOfPage()) {
currentPage++;
ajaxRunning = true;
jQuery.ajax('?page=' + currentPage, {asynchronous:true, evalScripts:true, method:'get',
beforeSend: function(){
$('.spinner').show();
},
success: function(data, textStatus, jqXHR) {
$('.spinner').hide();
$('#items_container').append(jQuery(data).find('#items_container').html());
if(typeof jQuery(data).find('.item').html() == 'undefined' || jQuery(data).find('.item').html().trim().length == 0 || currentPage == 10){
clearInterval(intervalID);
},
complete: function() {
ajaxRunning = false;
}
},});
}
}
Set async to false, or create a variable like
var isLoading = false;
In before send set it to true. On success set it false again. And before sending the ajax call, check if isLoading isn't true. If it is, return out of the function or put a loop inside with a spinner, which will be checking for the isLoading value so it fires the ajax first after isLoading was set to false.
Example:
function checkScroll() {
if (nearBottomOfPage() && isLoading === false) {
currentPage++;
jQuery.ajax('?page=' + currentPage, {asynchronous:true, evalScripts:true, method:'get',
beforeSend: function(){
var scroll = false;
$('.spinner').show();
isLoading = true;
},
success: function(data, textStatus, jqXHR) {
$('.spinner').hide();
$('#items_container').append(jQuery(data).find('#items_container').html());
var scroll = true;
if(typeof jQuery(data).find('.item').html() == 'undefined' || jQuery(data).find('.item').html().trim().length == 0 || currentPage == 10){
clearInterval(intervalID);
isLoading = false;
}
},
});
}}}