overwriting setInterval - javascript

I thought in the past that if I create a variable that I can overwrite them simple.
I'am trying to do the following:
var zoom = {
$el : $('#Overlay'),
nextTimer : null,
activeDetail : -1,
zo: null,
init: function() {
zoom.nextTimer = setInterval(zoom.nextLoop, 5000);
},
nextLoop: function() {
console.log("zoom.nextLoop");
}
}
$(document).on('click', function(e){
console.log("klick");
zoom.init();
});
and expected that the zoom.nextTimer will be overwritten. But it seems to be wrong, a new timer is added.
How can I overwrite it?
Please see also http://jsfiddle.net/9FXu6/

intervalID is a unique interval ID you can pass to clearInterval().
— https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval
The return value of setInterval is just a number that identifies the interval. You need to call clearInterval and pass it as the argument if you want to stop the interval from running the function again.
var nextTimer = setInterval(func, time);
clearInterval(nextTimer);

You need to call clearInterval(<reference to the timer>) to make sure it won't get executed again.
You might also have more luck with setTimout which only gets called once.

Related

Unexpected behavior with "SetInterval" in JavaScript

I have a JavaScript that makes request to a servlet. The request works but I can't get it to repeat at the specified time interval of 1 sec. What am I doing wrong?
I am quite new to front-end development and JavaScript.
$(document).ready(function() {
$('#userName').blur(function(event) {
var name = $('#userName').val();
setInterval($.get('JqueryServlet', {
userName : name
}, function(responseText) {
$('#ajaxResponse').text(responseText);}), 1000);
});
});
setInterval works with the arguments setInterval(callbackFunction, timingInMilliseconds).
It looks like you are putting your call to $.get directly in the callbackFunction argument. This unfortunately doesn't work as the result of your call to $.get is passed as the argument, not the function itself. Even if you did pass the function, it wouldn't be called with the proper arguments.
Instead wrap it in an anonymous function call or place it in a function, like so:
function getServlet() {
// code
}
setInterval(getServlet, 1000); // to go off every 1 second
Or:
setInterval(function() {
// code
}, 1000);
If you insisted on using $.get directly in setInterval, you could use something like:
setInterval(function(a,b,c){
console.log(a + b +c);
}, 500, "a", "b", "c");
In most browsers (see the link above) you can use setInterval with the call:
setInteval(callbackFunction, timingInMilliSeconds, callbackArg, callbackArg, ...);
Anything you want to do, put inside of this block below:
setInterval(function(){
alert("I will be called in 3 second and again after 3 seconds");
}, 3000);
Try it now with this:
$(document).ready(function() {
$('#userName').blur(function(event) {
var name = $('#userName').val();
setInterval(function(){
$.get('JqueryServlet', {
userName : name
}, function(responseText) {
$('#ajaxResponse').text(responseText);
});
}, 1000);
});
});
on any blur event you create new instance of interval and they remain in memory and can cause conflict ,create a global interval ref object and set interval reference to it and before start new interval dispose old interval.

problems with clearTimeout() in vue.js

i'm doing a shopping cart in vue but i'm having some issues. having never used the library i'm probably doing basics wrong, but:
when I add something to the cart I have an onclick function, expander(item) which looks like this:
this.addToCart(item);
this.show = true;
clearTimeout(this.timer);
timer: setTimeout(()=>{ this.show = false; }, 3000);
so what it does it adds to cart, sets the visibility of the cart div to true, then after a delay of three seconds it sets the cart div back to false.
the thing is, the clearTimeout(this.timer) doesn't work. so for each click, after three seconds, no matter what I do it sets the visibility back to false. what I'm trying to do with this function is to reset the timer each time and after reading up it seems like I'm doing it the correct way.
so, I'm guessing my problem is that i need to declare the variable
timer: setTimeout(()=>{ this.show = false; }, 3000);
outside of the function, in order for clearTimeout() to find it at the beginning of my function. my problem here is that wherever I declare it, it can't seem to find it. I've tried declaring the variable in my data {} and also outside of the Vue instance but it doesn't seem to want to find it in my functions.
so: how do I declare the variable? is that even my problem? is there may be an easier fix for this than what it's trying to do?
thanks!
In the quoted code, this line:
timer: setTimeout(()=>{ this.show = false; }, 3000);
defines a labelled statement, and doesn't save the timer handle anywhere. To save it to this.timer, you'd use an assignment:
this.timer = setTimeout(()=>{ this.show = false; }, 3000);
(The timer: thing would assign to a property within an object initializer [{ ... }], but not outside of one.)
wait 1 second between keypress,
if user keypress, clear setTimeout and renew setTimeout with more 1 second
after 1 second user dont keypress the before setTimeout expire and call another function(method in VueJs)
List item
I used this solution, it's verify if user end the word before call api:
data: {
search: '',
time:null,
},
watch: {
search: function (search) {
var self = this;
console.log('Search keypress: ' + search);
if (search.length >= 3) {
if (this.time) {
clearTimeout(this.time);
}
this.time = setTimeout( () => this.searchOnline(search), 1000);
console.log('Search online or wait user finish word?');
}
},
},
methods:{
searchOnline: function(search){
console.log('Start search online: ' + search);
// axios call api search endpoint
console.log('Serch online finished!');
},
}
setTimeout generates an id
capture this id in a variable
pass this variable to clearTimeout
as per MDN: The returned timeoutID is a positive integer value which identifies the timer created by the call to setTimeout(); this value can be passed to clearTimeout() to cancel the timeout.
In Vuejs the following steps work for me.
data: {
myToid:null,
}, ....
methods: {
myTofunction: function(){
clearTimeout(this.myToid);
this.myToid = setTimeout(() => {
...my function code...;
}, 6000);
}
}
Whenever I call myTofunction, it first clears any existing setTimeout id (stored in myToid) and then sets a new id.

What is the optimal way to use setInterval in jquery ajax calls?

I am using JQWidgets to create a pie chart. And while that is all fine and dandy and working like a charm. What I'd like to do however is update the data every x number of seconds. Using jQuery, here is the code that I have so far:
function loadChart(id,name){
//chart loads here
var speed = 5000,
t = setInterval(reloadData,speed);
function reloadData() {
source.url = 'data.php?id='+id;
var dataAdapter = new $.jqx.dataAdapter(source);
$('#pie').jqxChart({ source: dataAdapter });
console.log('reloading pie...'+globalPieId);
speed = 5000;
clearInterval(t);
t = setInterval(reloadData, speed);
}
}
My issue is, that if the loadChart function is called, another instance of setInterval is created, and after three or four times, the chart is in a constant state of refresh. How do optimize my setInterval call so that only one instance is called?
Thanks in advance.
Instead of using setInterval which calls the function over and over again you would be better off using the setTimeout function which will call the callback you specify just once. Once that callback is called you can once again call setTimeout and you'll stop having the problems you're having right now. Also you'll wait until the last call is done before you start doing another one which is also good. The code might look something like this with the change:
function loadChart(id,name){
//chart loads here
var speed = 5000,
t = setTimeout(reloadData,speed);
function reloadData() {
source.url = 'data.php?id='+id;
var dataAdapter = new $.jqx.dataAdapter(source);
$('#pie').jqxChart({ source: dataAdapter });
console.log('reloading pie...'+globalPieId);
speed = 5000;
t = setTimeout(reloadData, speed);
}
}
For a working poc you could see http://jsfiddle.net/9QFS2/
You need to clear existing interval before you set up a new one. Try the following trick.
function loadChart(id, name) {
// We use a trick to make our 'interval' var kinda static inside the function.
// Its value will not change between calls to loadChart().
var interval = null;
// This is the core of a trick: replace outer function with inner helper
// that remembers 'interval' in its scope.
loadChart = realLoadChart;
return realLoadChart(id, name);
function realLoadChart(id, name) {
var speed = 5000;
// Remove old interval if it exists, then set up a new one
interval && clearInterval(interval);
interval = setInterval(reloadData, speed);
function reloadData() {
// ... your code, but no do nothing with interval here ...
}
}
}

Can anyone explain why this JavaScript wont run

Im not very good wit JS and I just dont get why this wont work!
The code uses jquery to apply the pulsate efect to one of my divs and run forever unless I stop it with another function, but I cannot figure our why my first piece of code wont run!
function animate(var x){
// Do pulsate animation
$(x).effect("pulsate", { times:4 }, 5000);
// set timeout and recall after 10secs
setTimeout(animate, 10000);
}
$(document).ready(animate("#mydiv"));
Only way to get it working is for me to do this
function animate(){
// Do pulsate animation
$("#mydiv").effect("pulsate", { times:4 }, 5000);
// set timeout and recall after 10secs
setTimeout(animate, 10000);
}
$(document).ready(animate);
Note that in the first snippet the code uses variables to be more useful and the second piece has the selectors name hardcoded
Don't use var in your function declaration. Just use:
function animate(x){
Also, you probably want something like this for your first example:
function animate(x){
return function () {
function animateInner() {
$(x).effect("pulsate", { times:4 }, 5000);
setTimeout(animateInner, 10000);
}
animateInner();
};
}
$(document).ready(animate("#mydiv"));
DEMO: http://jsfiddle.net/XHKbC/
Otherwise, the original animate("#mydiv") call executes immediately (and $(x) probably won't find anything since the DOM isn't ready yet). $(document).ready() expects a reference to a function. You called a function instead. But that's all a little overkill. Just use:
$(document).ready(function () {
animate("#mydiv");
});
but you'll have to change your function so the setTimeout passes the value of x as well:
function animate(x){
// Do pulsate animation
$(x).effect("pulsate", { times:4 }, 5000);
// set timeout and recall after 10secs
setTimeout(function () {
animate(x);
}, 10000);
}
DEMO: http://jsfiddle.net/XHKbC/2/
Although it's a little more code/complex, my first example doesn't suffer the problem in my second (having to pass x in the setTimeout) by using a closure.
UPDATE:
Being shown how you are using this code, I'd set it up like this:
function Animater(target) {
var self = this;
var animateTO;
var animateElement = target;
function animate() {
animateElement.effect("pulsate", { times:4 }, 5000);
animateTO = setTimeout(animate, 10000);
}
self.start = function () {
animate();
};
self.stop = function () {
animateElement.finish();
clearTimeout(animateTO);
};
}
And create a new one like:
var mydivAnimater = new Animater($("#mydiv"));
You can then call .start() and .stop() on it, and you create any number of these Animater objects on different elements as you want.
DEMO: http://jsfiddle.net/K7bQC/3/
Your code has two issues:
omit the var:
function animate(x){
modify your event handler:
$(document).ready(function(){
animate("#mydiv");
});
You need to hand over a function reference (either animate or function(){}), not run the code right away which you are doing if you pass animate().
Now to not lose the reference to your x you have to modify the animate call in the timeout too:
setTimeout(function () {
animate(x);
}, 10000);
You dont need to type var when specifying a function parameter.

JavaScript: window.setTimeout(), force early expire

I have a <div> on my page that refreshes automatically every two minutes with updated log entries. When I first load my webpage, I call the following function.
function getLogs() {
var filter = $('#filter').val();
$.get("index-ajax.asp", { queryType: "getLogs", filter: filter,
uTime: new Date().getTime() },
function(data){
$("#logEntries").html(data);
window.setTimeout("getLogs()",120000);
});
}
I know the above code could be cleaner with window.setInterval(...); but I just like the control of window.setTimeout(...);.
My question, is it possible to cancel the next timeout execution? In the event that I change the filter, I'd like to cancel the next timeout, and call the function right away, which would reschedule the timeout function. Is there a better way to achieve that result?
Note that the above code is in jQuery.
Yes, use clearTimeout.
Ex:
var clr = window.setTimeout(getLogs,120000);
The when you wan to clear it:
clearTimeout(clr);
setTimeout returns a timerID that you can pass to clearTimeout:
// Note we are passing the *function* rather than a string
// Also note the lack of () - we are *not* calling the function
// setTimeout will do that for us
var timerID = setTimeout(getLogs, 120000);
// Fake condition - we cancel the timer if the timerID is even
if (timerID % 2 === 0) {
clearTimeout(timerID);
}
You could always define a new variable based on a filter value and if that filter value is set, use a while statement to omit the timeout:
if(filter == "whatevs"){
var i=true;
}
function(data){
$("#logEntries").html(data);
while(i!=true){
window.setTimeout("getLogs()",120000);
}
}

Categories

Resources