Javascript setInterval within setInterval timer increasing - javascript

I have an ajax request that refreshes a page using setInterval every 5 seconds.
Within that ajax request I have another setInterval function to blink a every half second if a condition is true.
What happens is it seems to work fine after the initial ajax call. However, with every 5 second refresh ajax refresh, my blink function timer is halved, effectively doubling the speed.
Any help would be appreciated, thanks!
Here is the code:
$(document).ready(function() {
var refreshRate = 5000;
var autoRefresh = setInterval(
function () // Call out to get the time
{
$.ajax({
type: 'GET',
success: function(data){
document.getElementById('data').innerHTML=data;
var blink = setInterval (function () {
var blink_cell = $("#blink_div").html();
if (blink_cell > 0) {
$("#blink_div").toggleClass("blink");
} else {
$("#blink_div").addClass("invisible");
}
},500);
} // end success
}); // end ajax call
}, refreshRate);// end check
}); // end ready

Be concerned with the scope of your variables and clear the blink intervall before initiating a new one.
$(document).ready(function() {
var refreshRate = 5000;
var blink = -1;
var autoRefresh = setInterval(
function () // Call out to get the time
{
$.ajax({
type: 'GET',
success: function(data){
document.getElementById('data').innerHTML=data;
if(blink>-1) clearInterval(blink);
blink = setInterval (function () {
var blink_cell = $("#blink_div").html();
if (blink_cell > 0) {
$("#blink_div").toggleClass("blink");
} else {
$("#blink_div").addClass("invisible");
}
},500);
} // end success
}); // end ajax call
}, refreshRate);// end check
}); // end ready

$(document).ready(function () {
var _url = ''; // Put your URL here.
var _checkServerTime = 5000;
var _blinkTime = 500;
function _blink() {
// Do something here.
var condition = true; // Put condition here.
if (condition) setTimeout(_blink, _blinkTime);
}
function _handleData(data) {
$('#data').html(data);
_blink();
}
function _checkServer() {
$.get(_url, _handleData);
}
setInterval(_checkServer, _checkServerTime);
});

Related

JSON jQuery Refresh

I want to reload data via javascript/jQuery into html div id elements every second. The initial load (ready-state) works perfectly, but in the refresh (via setInterval()) doesn't. I'm just a hobbyist programmer and would be very thankful for your help.
$(document).ready(function() {
$.getJSON('db/blackmagic/webscripts/jquery_gpio.php', function(json_php) {
document.getElementById("jq_zeitstempel").innerHTML = json_php.jq_zeitstempel;
document.getElementById("jq_bcm05").innerHTML = json_php.jq_bcm05;
document.getElementById("jq_bcm06").innerHTML = json_php.jq_bcm06;
setInterval(function() {
$.getJSON('db/blackmagic/webscripts/jquery_gpio.php', function(json_php_refresh) {
document.getElementById("jq_zeitstempel").innerHTML = json_php_refresh.jq_zeitstempel;
document.getElementById("jq_bcm05").innerHTML = json_php_refresh.jq_bcm05;
document.getElementById("jq_bcm06").innerHTML = json_php_refresh.jq_bcm06;
}
}, 1000);
});
});
I would create a single function instead and just call that in interval.
loadjSON = function() {
$.getJSON('db/blackmagic/webscripts/jquery_gpio.php', function(json_php) {
document.getElementById("jq_zeitstempel").innerHTML = json_php.jq_zeitstempel;
document.getElementById("jq_bcm05").innerHTML = json_php.jq_bcm05;
document.getElementById("jq_bcm06").innerHTML = json_php.jq_bcm06;
});
}
$(document).ready(function() {
setInterval(loadjSON, 1000);
});
Ex 1
In case, when you want to do the request no matter if previous was finished or not - you can wrap whole your logic in setInterval, like this:
$(document).ready(function () {
setInterval(function() {
$.getJSON("db/blackmagic/webscripts/jquery_gpio.php", function (json_php) {
document.getElementById("jq_zeitstempel").innerHTML = json_php.jq_zeitstempel;
document.getElementById("jq_bcm05").innerHTML = json_php.jq_bcm05;
document.getElementById("jq_bcm06").innerHTML = json_php.jq_bcm06;
});
}, 1000);
});
Ex 2
But if you need to wait a second after previous was finished, you can do kind of recursion here.
$(document).ready(function () {
function getJSON() {
$.getJSON("db/blackmagic/webscripts/jquery_gpio.php", function (json_php) {
document.getElementById("jq_zeitstempel").innerHTML = json_php.jq_zeitstempel;
document.getElementById("jq_bcm05").innerHTML = json_php.jq_bcm05;
document.getElementById("jq_bcm06").innerHTML = json_php.jq_bcm06;
setTimeout(getJSON, 1000);
});
}
getJSON();
});
How it works
In first example it simply calls your function every second.
In second, we wrap your function and call itself at the end of the request, after a second of waiting.

How to make JavaScript countdown timer work again and again on clicking a button?

On clicking a button with id next-problem , an AJAX request is send to server and new task get loaded. I want to restart the timer when new task get loaded. In AJAX , on success I want to reset timer. But the problem is many setInterval get starts on click the button. How to avoid that ?
var timer;
var countdownfunction;
var countDownTime;
timer = function (){
clearInterval(countdownfunction);
countDownTime = $("#timer").attr("data-timer-val");
var countdownfunction = setInterval(function() {
if(countDownTime < 10 ){
var temp = "0" + countDownTime;
$("#time").text(temp);
}else{
$("#time").text(countDownTime);
}
countDownTime = countDownTime - 1;
if (countDownTime < 0) {
clearInterval(countdownfunction);
$("#time-expired").text("Please click next problem.");
}
}, 1000);
} ;
$(document).ready(function(){
timer();
});
$(document).ready(function(){
$("#next-problem").on('click', function(){
$.ajax({
type : 'POST',
url : '/test/next-problem/',
success : function(data){
// console.log(data);
$("#problem-content").html(data);
clearInterval(countdownfunction);
timer();
},
});
});
});
Remove var from the following line:
var countdownfunction = setInterval(function() {
Because of this var you have two differently scoped values of countdownfunction so when you call clearInterval you are never clearing this particular functionally-scoped value until that timer reaches -1, so you may have multiple timers running on top of each other.
Once you remove var here, you now have a single, globally-scoped variable that can be cleared and reassigned a value.

setInterval keeps stacking even with clearInterval

I'm making a simple punch in / punch out timer.
Problem im facing is that it works perfectly on page load but when the user clicks end_work_btn then begin_work_btn, the timer kinda stacks the initial value and the new one starting from 0 so it's trying to display both. It keeps stacking everytime they click the buttons until page reload when it resets.
I've done a bunch of reading and figured clearInterval(timer) would do it but no go so assuming i'm not using it correctly or i'm way off the ball on whats wrong here.
Here's what I got so far
<button id="begin_work_btn">Begin Work</button>
<button id="end_work_btn"><span id="hours"></span>:<span id="minutes"></span>:<span id="seconds"></span></button>
<script>
var emp_id = '2';
var timer = null;
function reset_timer(time){
var sec = time;
clearInterval(timer);
function pad ( val ) {
return val > 9 ? val : "0" + val;
}
var timer = setInterval( function(){
$("#seconds").html(pad(++sec%60));
$("#minutes").html(pad(parseInt(sec/60,10)%60));
$("#hours").html(pad(parseInt(sec/3600,10)));
}, 1000);
}
reset_timer(<?php echo $existing_time;?>);
$("#begin_work_btn").click(function(){
$.ajax({
type: "post",
url: "<?php echo $url;?>process.php",
data: "agent_id="+emp_id+"&action=begin_work",
success: function(data){
var sec = 0;
reset_timer(sec);
$('#begin_work_btn').hide();
$('#end_work_btn').show();
}
});
});
$("#end_work_btn").click(function(){
$.ajax({
type: "post",
url: "<?php echo $url;?>process.php",
data: "agent_id="+emp_id+"&action=end_work",
success: function(data){
$('#end_work_btn').hide();
$('#begin_work_btn').show();
}
});
});
</script>
Pretty simple, scope is different. In your code you have two variables named timer. The one inside the function is created each time reset_timer is called. One outside never gets a value. So each time you call the function, another instance of timer is created.
var timer = null; //<-- outside
function reset_timer(time){
clearInterval(timer);
var timer = setInterval( ... , 1000); //<--redefined inside so each time, it creates new variable
}
You basically have this:
function reset_timer(time){
var timer;
clearInterval(timer);
timer = setInterval( ... , 1000);
}
It should not be defined with var. This way it updates the variable defined outside of the function each time it is called.
var timer = null;
function reset_timer(time){
if (timer) clearInterval(timer);
timer = setInterval( ... , 1000); //<--no more var
}

simple ajax request with interval

I recently began learning Ajax and jQuery. So yesterday I started to programm a simple ajax request for a formular, that sends a select list value to a php script and reads something out of a database.
It works so far!
But the problem is, that when I click on the send button, it starts the request, 1 second later. I know that it has something to do with my interval. When I click on the send button, I start the request and every second it requests it also, so that I have the opportunity, to auto-refresh new income entries.
But I'd like to have that interval cycle every second, but the first time I press the button it should load immediately, not just 1 second later.
Here is my code:
http://jsbin.com/qitojawuva/1/edit
$(document).ready(function () {
var interval = 0;
$("#form1").submit(function () {
if (interval === 0) {
interval = setInterval(function () {
var url = "tbladen.php";
var data = $("#form1").serialize();
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
$("#tbladen").html(data);
}
});
}, 1000);
}
return false;
});
});
Thanks!
I might be something like the following you're looking for.
$(document).ready(function () {
var isFirstTime = true;
function sendForm() {
var url = "tbladen.php";
var data = $("#form1").serialize();
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
$("#tbladen").html(data);
}
});
}
$("#form1").submit(function () {
if (isFirstTime) {
sendForm();
isFirstTime = false;
} else {
setTimeout(function () {
sendForm();
}, 1000);
}
return false;
});
});
So, use setTimeout when the callback has finished as setInterval just keeps running whether or not your callback has finished.
$(function () {
$("#form1").submit(postData);
function postData() {
var url = "tbladen.php",
data = $("#form1").serialize();
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
$("#tbladen").html(data);
setTimeout(postData, 1000);
}
});
return false;
}
});
Kind of related demo

Javascript : Do Action after elapsed time

I have a page where I fire an ajax request AND show a loading sign for the first 6 seconds after the user presses a button :
<button onclick="runLoader();"></button>
<script>
var startTime=(new Date).getTime();
function runLoader(){
runAjax();
var i=0;
var timer = setInterval(function(e){
i++;
//code for loading sign
if(i==3)
clearInterval(timer);
} ,2000);
}
function runAjax(){
$.ajax({
//
}).done(function(){
var timer2 = setInterval(function(){
var d = new Date();
var t = d.getTime();
if(t-startTime>=6000){
clearInterval(timer2);
// do X
}
},500);
}
}
</script>
I want to do action X only after both runLoader() has run for 6 seconds and runAjax() has resulted in a response, and no sooner.
Like, if runAjax() responds in 2 seconds, I still want to continue showing loading sign for 6 seconds and then perform X.
And if the loading sign has shown for 6 seconds, I want to wait for runAjax() to return for as long as it takes.
But using the Date() method is giving inaccurate results. For eg : It shows 7.765 s elapsed even when only 2 s have passed. I read somewhere I should use console.log(time) for better accuracy, but it doesnt work in <=IE9.
Is there a better way to approach this problem ?
Note: I am using setInterval() instead of setTimeout() because the loading involves cycling through an array of 3 elements, "Fetching", "Processing" and "Loading" each shown for 2 seconds :)
I would use deferreds and $.when:
function start(){
$.when(runLoader(), runAjax()).done(function() {
//both are now finished
});
}
function runLoader() {
//show loader here
var def = $.Deferred();
setTimeout(function() {
//hide loader here
def.resolve(true);
}, 6000);
return def.promise();
}
function runAjax() {
var def = $.Deferred();
$.ajax({...}).done(function(result) {
//handle response here
def.resolve(true);
});
return def.promise();
}
I would set a flag to mark it as "ready". There may be better ways to handle this, but this is just off the top of my head.
<script>
function runLoader(){
runAjax();
var i=0;
var timer = setInterval(function(e){
i++;
//code for loading sign
if(i==3)
clearInterval(timer);
} ,2000);
}
function runAjax(){
var timeElapsed = false;
setTimeout(function(){timeElapsed = true}, 6000);
$.ajax({
//
}).done(function(){
var timer2 = setInterval(function(){
if(timeElapsed){
clearInterval(timer2);
// do X
}
},500);
}
}
</script>
You can create a pre-caller function that is run on runLoader() and as callback of runAjax(), that will verify if the other action is complete, and then do action X. Example:
var ajaxDone = false;
var loaderDone = false;
function doActionX() {
//your action happens here
}
function tryToDoX() {
if (ajaxDone && loaderDone) {
doActionX();
}
}
function runLoader(){
loaderDone = false;
runAjax();
//show loading sign
setInterval(function(e){
//hide loading sign
clearInterval(timer);
loaderDone = true;
tryToDoX();
}, 6000);
}
function runAjax(){
ajaxDone = false;
$.ajax({
//whatever
}).done(function(){
ajaxDone = true;
tryToDoX();
}
}
It isn't necessary to make a recurring timeout and poll both statuses, because they only get completed once (in every run, i.e. booleans aren't set to false and true while waiting).
EDIT: This approach can be used to any asynchronous code that doesn't change status intermitently, even without jQuery.

Categories