Last updated: Apr 4, 2024
Reading timeยท7 min
Note: if you're running into issues when using
setInterval()
, click on the following subheading:
The setTimeout
function might not work in JavaScript if you call it
incorrectly, e.g. by passing it the result of calling the callback function.
// โ๏ธ TypeError [ERR_INVALID_ARG_TYPE]: The "callback" argument must be of type function. Received undefined setTimeout(callbackFn(), 1000); function callbackFn() { console.log('bobbyhadz.com'); }
The issue in the example is that we are calling the callback function with
parentheses ()
in the call to setTimeout
.
setTimeout
method expects to get called with a reference to a function and not the result of calling one.You can resolve the issue by removing the parentheses and passing a reference to
a function to setTimeout
.
setTimeout(callbackFn, 1000); function callbackFn() { console.log('bobbyhadz.com'); }
The callbackFn
function is invoked after 1 second (1000 milliseconds) in the
example.
The setTimeout() method sets a timer that runs a function once the timer expires.
In some cases, you might want to pass one or more arguments to the function.
setTimeout(() => greet('bobby hadz'), 1000); function greet(name) { console.log(`hello ${name}`); }
The greet
function takes a name
argument, so we used an inline arrow
function in the call to setTimeout
.
This way we are still passing a reference to a function to setTimeout
but when
the function is invoked, it returns the result of calling greet
with the
string bobby hadz
.
If you only pass a reference to the greet
function to setTimeout
, then the
name
parameter will be undefined
.
// ๐๏ธ hello undefined setTimeout(greet, 1000); function greet(name) { console.log(`hello ${name}`); }
The previous example used an inline arrow function to resolve this, but you can
also pass the parameters you want to pass to the callback function directly to
setTimeout
.
// ๐๏ธ hello bobby hadz setTimeout(greet, 1000, 'bobby hadz'); function greet(name) { console.log(`hello ${name}`); }
The third argument we passed to setTimeout
is passed to the greet
function
when it gets called after 1 second (1000 milliseconds).
You can use this approach to supply as many parameters as necessary to the callback function.
// ๐๏ธ hello bobby hadz setTimeout(greet, 1000, 'bobby', 'hadz'); function greet(first, last) { console.log(`hello ${first} ${last}`); }
The third and fourth arguments we passed to setTimeout
get passed to the
greet
function when it gets called after 1 second.
You can either use an inline arrow function as we did in the previous example or
supply the additional parameters after the delay parameter in the call to
setTimeout
, however, make sure that you aren't calling the callback function
with parentheses ()
in the call to setTimeout
.
// โ๏ธ INCORRECT: callback called with parentheses () โ๏ธ setTimeout(callbackFn(), 1000); function callbackFn() { console.log('bobbyhadz.com'); }
When you add parentheses to a function, you invoke it immediately and the goal is to invoke a function after N milliseconds.
Another common cause for setTimeout
not to work is when you pass it a string
instead of a function.
Here is an example.
// โ๏ธ TypeError [ERR_INVALID_ARG_TYPE]: The "callback" argument must be of type function. Received type string ('callbackFn') setTimeout('callbackFn', 1000); function callbackFn() { console.log('bobbyhadz.com'); }
Notice that we passed a string as the first argument to setTimeout
.
The method expects to get called with a reference to a function and not a string.
// โ works as expected setTimeout(callbackFn, 1000); function callbackFn() { console.log('bobbyhadz.com'); }
Passing a reference to a function as the first argument to setTimeout
works as
expected.
Here is an example of calling the setTimeout()
method that may look confusing
at first.
setTimeout(() => { console.log('First line'); }, 0); console.log('Second line');
Running the code above produces the following output.
Second line First line
The example tries to run a function that logs a message to the console after 0
milliseconds.
One would expect that the First line
message would get printed first, however,
that's not the case.
When the setTimeout()
method is called, it gets added to the event table.
Only then will the event loop move the waiting events to the call stack for them to get processed.
The callback function we passed to setTimeout
gets queued for execution,
however, it is only executed after the call stack is empty and the second
console.log()
call has run.
If you encounter issues when trying to clear the timeout with the clearTimeout
method, make sure to store the timeout ID that is returned from calling
setTimeout
.
// ๐๏ธ store timeout ID in variable const timeoutID = setTimeout(callbackFn, 1000); // ๐๏ธ this clears the timeout clearInterval(timeoutID); function callbackFn() { console.log('bobbyhadz.com'); }
The example clears the timeout immediately.
You will most likely want to clear the timeout if a certain condition is met.
The setTimeout
method returns an ID that can be passed to the
clearTimeout()
method to clear the timeout.
The clearTimeout
method cancels a timeout that was previously set up by a call
to setTimeout
.
If you pass a parameter to the clearTimeout
method that is not the ID that is
returned from calling setTimeout
, then the clearTimeout
method does nothing.
A common reason for setInterval
not to work is when you pass a string to the
method instead of passing it a reference to a callback function.
Here is an example.
// โ๏ธ TypeError [ERR_INVALID_ARG_TYPE]: The "callback" argument must be of type function. Received type string ('callbackFn') setInterval('callbackFn', 1000); function callbackFn() { console.log('bobbyhadz.com'); }
Notice that we passed a string instead of a reference to a callback function to
setInterval
.
Instead, pass a reference to the function to setInterval
.
// โ works as expected setInterval(callbackFn, 1000); function callbackFn() { console.log('bobbyhadz.com'); }
The setInterval method takes a function and a delay in milliseconds and repeatedly calls the function with the specified delay between each call.
setInterval
Another common reason for setInterval
not to work is if you invoke the
callback function you passed to the method with parentheses ()
.
Here is an example.
// โ๏ธ TypeError [ERR_INVALID_ARG_TYPE]: The "callback" argument must be of type function. Received undefined setInterval(callbackFn(), 1000); // ๐๏ธ notice parentheses () function callbackFn() { console.log('bobbyhadz.com'); }
Notice that we used parentheses to call callbackFn()
in the call to the
setInterval
method.
To resolve the error, remove the parentheses as setInterval
expects to get
called with a reference to a function and not the result of calling a function.
// โ Works as expected setInterval(callbackFn, 1000); // ๐๏ธ removed parentheses function callbackFn() { console.log('bobbyhadz.com'); }
If you have to pass arguments to the callback function, use an inline arrow function wrapper.
// ๐๏ธ hello bobby hadz setInterval(() => greet('bobby hadz'), 1000); function greet(name) { console.log(`hello ${name}`); }
The arrow function returns the result of calling greet
with the string
bobby hadz
.
We are still passing a reference to a function to setInterval
, so everything
works as expected.
You can also pass arguments to the callback function by specifying them after
the delay parameter in the call to setInterval
.
setInterval(func, delay, arg0, arg1, ...)
Here is an example.
// ๐๏ธ hello bobby hadz setInterval(greet, 1000, 'bobby hadz'); function greet(name) { console.log(`hello ${name}`); }
The argument we passed after the delay of 1000 milliseconds (1 second) gets
passed to the greet
function after the specified delay.
The same approach can be used to pass multiple arguments to the callback function.
// ๐๏ธ hello bobby hadz setInterval(greet, 1000, 'bobby', 'hadz'); function greet(first, last) { console.log(`hello ${first} ${last}`); }
The code sample produces the same output however, this time we passed 2
arguments to the callback function (greet
).
We used 1000 milliseconds as the delay in the examples.
The delay
parameter is used to specify the time, in milliseconds (1000
milliseconds = 1 second), the timer should delay in between executions of the
supplied function.
If you encounter issues when trying to clear the interval with the
clearInterval
method, make sure to store the interval ID that is returned from
calling setInterval
.
// ๐๏ธ store interval ID in variable const intervalID = setInterval(callbackFn, 1000); // ๐๏ธ this clears the interval clearInterval(intervalID); function callbackFn() { console.log('bobbyhadz.com'); }
The example clears the interval immediately.
You will most likely want to clear the interval if a certain condition is met.
The setInterval
method returns an ID that can be passed to the
clearInterval()
method to clear the interval.
The clearInterval
method cancels a timed, repeating action that was previously
set up by a call to setInterval
.
If you pass a parameter to the clearInterval
method that is not the ID that is
returned from calling setInterval
, then the clearInterval
method does
nothing.
You can learn more about the related topics by checking out the following tutorials: