Uncaught SyntaxError while using setInterval Javascript [duplicate] - javascript

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 4 years ago.
I am using the below code to play an audio file for every second, the audio file is a second long and it basically a tick. The code will run only once and then I see the error in the console. My intention is to make it run every second until something is achieve then I can clear the Interval. This is the error I am getting in the console
Uncaught SyntaxError: Unexpected identifier
setInterval (async)
This is my code:
$('select[name=notsound]').change(function(){
var h = $(this).val();
var tickAudio = new Audio('https://www.sample.com/sounds/'+h+'');
setInterval(tickAudio.play(),1000);
});
I am not sure why is this happening, I am sure that I have made some error which is causing this issue, as it was working before I thought of giving it a different approach. Thank you for reading my query. :)

Method play needs to be called in the context of the right object:
var cleartick = setInterval(tickAudio.play.bind(tickAudio),1000);
The second suggestion of #rmlan will also work.
Clearing interval is the same - you need not to call a function, but to pass a function reference to setTimeout:
setTimeout(clearInterval, 3000, cleartick);
setInterval/setTimeout have a convenient way of passing parameters to timer functions - as cleartick above.

You are currently "executing" the result of tickAudio.play() every second, instead of executing the function itself.
To remedy this, you can either pass the function as an object:
setInterval(tickAudio.play.bind(tickAudio),1000);
Or wrap the call in an anonymous function:
setInterval(function () { tickAudio.play() },1000);

Related

Javascript code doesn't work as expected [duplicate]

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 6 years ago.
I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).
$scope.clickFilter = function () {
var filter = $('.filter-item')
.find('input[value="' + $scope.activeFilter + '"]');
if (filter.length < 1) {
setTimeout($scope.clickFilter(), 1000);
} else {
$(filter).trigger("click");
}
}
However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"
How do I prevent this and make sure it runs until completion?
The problem is here:
setTimeout($scope.clickFilter(), 1000);
Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:
setTimeout($scope.clickFilter.bind($scope), 1000);
which will
pass a function reference to setTimeout(), as is required, and
ensure that the function will be invoked with the proper this value (what the .bind() part does)
Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

JavaScript setInterval callback before defining function? [duplicate]

This question already has answers here:
Why can I use a function before it's defined in JavaScript?
(7 answers)
Closed 5 years ago.
I'm currently a teacher's assistant in a web development course. Today, a student asked for help with his homework, in which he'd used setInterval, passing as the first parameter a function which he didn't define until a few lines of code later. I told him that wouldn't work, as the function would be undefined by the time the interval setting code was reached.
To my surprise, it worked perfectly. I've been trying to research this and am coming up blank: does JavaScript actually wait until the first execution of the callback to even see if the function name passed to it exists? That seems so counter-intuitive, but I can't imagine any other reason it would have worked. Where can I find out more about this unexpected behavior?
It depends:
If its a function expression :
//callback not defined ( exists but undefined)
var callback=function(){};
//callback defined
If its a function declaration :
//callback is defined
function callback(){}
//callback is defined
This is called hoisting, so vars and functions are moved to the top.
It also depends on the passed function too:
setInterval(callback,0);//doesnt work, callback is *undefined* in this moment
setInterval(function(){ callback();},100);//does work as callback is just called before being referenced.
var callback=function(){};

Why does html onclick runs when it added by javascript [duplicate]

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 6 years ago.
I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).
$scope.clickFilter = function () {
var filter = $('.filter-item')
.find('input[value="' + $scope.activeFilter + '"]');
if (filter.length < 1) {
setTimeout($scope.clickFilter(), 1000);
} else {
$(filter).trigger("click");
}
}
However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"
How do I prevent this and make sure it runs until completion?
The problem is here:
setTimeout($scope.clickFilter(), 1000);
Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:
setTimeout($scope.clickFilter.bind($scope), 1000);
which will
pass a function reference to setTimeout(), as is required, and
ensure that the function will be invoked with the proper this value (what the .bind() part does)
Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

Maximum call stack size exceeded on SetTimeout recursive function (Javascript) [duplicate]

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 6 years ago.
I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).
$scope.clickFilter = function () {
var filter = $('.filter-item')
.find('input[value="' + $scope.activeFilter + '"]');
if (filter.length < 1) {
setTimeout($scope.clickFilter(), 1000);
} else {
$(filter).trigger("click");
}
}
However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"
How do I prevent this and make sure it runs until completion?
The problem is here:
setTimeout($scope.clickFilter(), 1000);
Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:
setTimeout($scope.clickFilter.bind($scope), 1000);
which will
pass a function reference to setTimeout(), as is required, and
ensure that the function will be invoked with the proper this value (what the .bind() part does)
Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

Repeating a script using setInterval() [duplicate]

This question already has answers here:
setTimeout ignores timeout? (Fires immediately) [duplicate]
(3 answers)
Closed 8 years ago.
I'm working on a Chrome extension to fetch tweets and I figured that I could use the setInterval() function to make the script run every minute. First I tried giving it the function like this:
setInterval(myFunction(), interval);
But it would only execute my script once.
Then out of curiosity I tried declaring the function in the setInterval() function like so:
setInterval(function() {body of my function}, interval);
And that works, but is not a very pretty solution, does anybody any other way of doing this or am I just going to have to deal with it?
Just remove the brackets from the first call. The reason for this is that you need to pass in the function, not the result of the function (what it returns).
When you write the function's name with brackets, it calls the function. When you exclude the brackets, it simply refers to the function like a variable, and so you can pass in your function to the setInterval() function.
setInterval(myFunction, interval);

Categories

Resources