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.
Related
if (msg.content.toLowerCase() === "!start") {
var gov = setInterval(go, 1000);
var onev = setInterval(one, 1000);
var twov = setInterval(two, 1000);
function two(msg) {
msg.channel.send("https://i.imgur.com/JZOCg5l.png ");
}
function one(msg) {
msg.channel.send("https://i.imgur.com/gTK3Vhn.png ");
}
function go(msg) {
msg.channel.send("https://i.imgur.com/3iVfYIR.png ");
}
function two(msg) { }
function one(msg) { }
function go(msg) { }
msg.channel.sendFile("https://i.imgur.com/kOoyoZQ.png ").then(onev).then(twov).then(gov);
}
This is a very annoying task. I need to send these images about one second appart.
The current framework keeps giving me the following error:
C:\Users\maver\Documents\TestBot\testlev.js:197
msg.channel.sendFile("https://i.imgur.com/3iVfYIR.png ");
^
TypeError: Cannot read property 'channel' of undefined at Timeout.three [as _onTimeout]
(C:\Users\maver\Documents\TestBot\testlev.js:197:17)
at ontimeout (timers.js:478:11)
at tryOnTimeout (timers.js:302:5)
at Timer.listOnTimeout (timers.js:262:5)
I've tried this a multitude of different ways and am just about ready to throw in the towel.
Your syntax is slightly off. When you do function two(msg){... you are actually telling the function that you are going to pass it a new variable and that you want that variable called msg. Because of that, msg (in the context of your function) is undefined. You would have to pass in msg when you call the function from setInterval().
There are 2 ways you can bind msg to your function. The way that I personally like is this:
//...
var gov = setInterval(go.bind(null, msg), 1000);
var onev = setInterval(one.bind(null, msg), 1000);
var twov = setInterval(two.bind(null, msg), 1000);
//...
The .bind() function assigns the value of arguments. With the first argument of the function being called being the second argument of bind(). The first argument of bind() is what should be used as the value of this inside the function.
The other way to do this is with an anonymous function
//...
var gov = setInterval(function(){go(msg)}, 1000);
var onev = setInterval(function(){one(msg)}, 1000);
var twov = setInterval(function(){two(msg)}, 1000);
//...
Also note, setInterval() repeats a function call ever period. You may be looking for setTimeout() which would only fire the functions once after a delay.
When you use setInterval, you should know it will call the function, but will not provide any parameters to it (or even this). One way to fix it would be by using bind:
setInterval(go.bind(null, msg), 1000)
This would work, because bind() will create a new function where the parameters are "magically set in advance".
Another option in this case would be to simply not re-declare msg in the three functions - in that case, javascript will try to find msg from the outer scope, where it exists:
function two() {
msg.channel.send("https://i.imgur.com/JZOCg5l.png ");
}
Third, you shouldn't be using setInterval, but setTimeout, which will only call the function once.
The fourth problem you have is with timing. First, all three setTimeout calls happen at the same time, so all three functions will be called in one second (after 1000 millis). An easy fix would be simply:
setTimeout(go, 1000);
setTimeout(one, 2000);
setTimeout(two, 3000);
However, that will completely ignore how long it takes to send each message (which may or may not be what you want). If you wanted to wait a second after the previous message is sent, then you'd have to do something like:
msg.channel.sendFile("https://i.imgur.com/kOoyoZQ.png ").then(function() {
setTimeout(go, 1000);
});
function go() {
msg.channel.send("https://i.imgur.com/3iVfYIR.png").then(function() {
setTimeout(one, 1000);
});
}
// etc
That would be very tedious, as all the functions will look very similar. So a better approach would be to create a list of messages, then have a single function to send all of them:
var msgs = [
"https://i.imgur.com/kOoyoZQ.png",
"https://i.imgur.com/JZOCg5l.png",
"https://i.imgur.com/gTK3Vhn.png",
"https://i.imgur.com/3iVfYIR.png"
];
function sendMsgs(msgs, delay) {
if (msgs.length < 1) return; // we're done
var remain = msgs.slice(1);
var sendRemain = sendMsgs.bind(null, remain, delay);
msg.channel.send(msgs[0]).then(function() {
setTimeout(sendRemain, delay);
});
}
sendMsgs(msgs, 1000);
Your code is executed immediately because you have to maintain the value anf promises you are using is not correctly used.
You can do it as follows :
if (msg.content.toLowerCase() === "!start") {
var urls = ["https://i.imgur.com/kOoyoZQ.png",
"https://i.imgur.com/JZOCg5l.png",
"https://i.imgur.com/gTK3Vhn.png",
"https://i.imgur.com/3iVfYIR.png" ];
function gov(urls){
for(let k=0; k<urls.length;k++){
setTimeout(function() { msg.channel.send(k); },k*1000)
}
}
gov(urls);
}
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.
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.
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);
}
}
I have function called rotator(id): this function animate div and I can called this function with different id for animate different elements
Actually I use 5 differents id , 1,2,3,4,5
And for call I need put :
rotador(1);rotador(2);rotador(3);rotador(4);rotador(5);
The problem it´s that I want to rotate in automatic mode. For this I think to use this
for (i=0;i<=5;i++) {
setTimeout(rotador(i),2000);
}
But it doesn't work because it animates all in the same time, no let firt execute the first and continue before of first go second , etc , etc and when go the end or number 5 start other time in one
My problem it´s this if you can help me THANKS !!! :) Regards
You are actually calling the rodator(i) function, and schedule for execution after 2 seconds the result of the rodator. In other words, your code is now equalent to:
for (i=0;i<=5;i++) {
var result = rotador(i);
setTimeout(result,2000);
}
You can accomplish this either by creating a function for the callback:
for (i=0;i<=5;i++) {
setTimeout((function(i){
return function(){
rotador(i);
}
})(i),2000 * i);
}
or you can call the next rodator in the rotador function itself:
var rotador = function(i){
// your code
if (i < 5) {
setTimeout(function(){rotaror(i + 1);}, 2000);
}
}
Note: the closure in the second example is needed to call the function with the correct value of i. We are creating an anonymous function, and create i as a local scope variable, which value won't be mutated by the outerscope changes. (we can rename i to n in the local scope, if this would be more readable). Otherwise the value of i will be 5 each time rotador is called, as the value of i would be modified before the actual function call.
since setTimeout() does not wait for the function to be executed before continuing, you have to set the delay to a different value for different items, something like 2000 * (i + 1) instead of just 2000
EDIT: yes, and you need the callback as Darhazer suggests
rotationStep(1);
function rotador(id)
{
console.log(id);
}
function rotationStep( currentId )
{
rotador(currentId);
var nextId = currentId<5 ? currentId+1 : 1;
setTimeout(function(){ rotationStep(nextId) },2000); //anonymous function is a way to pass parameter in IE
}
Use a callback:
setTimeout(function() {
rotador(i)
}, 2000)