3

When I execute the following, incidentController gets called after 10 seconds and continues to execute with no problems every 10 seconds:

// This works fine in nodejs v0.11.13
setInterval(incidentController, 10 * 1000);

function incidentController () {
 console.log ('executed'); 
}

However, this executes immediately and throws the following error on the second iteration:

//This doesn't. The parens which wrap (123) cause the error.

setInterval(incidentController(123), 10 * 1000);

function incidentController (someInt) {
 console.log ('executed: ', someInt); 
}

Error:

timers.js:287
    callback.apply(this, args);
            ^
TypeError: Cannot read property 'apply' of undefined
    at wrapper [as _onTimeout] (timers.js:287:13)
    at Timer.listOnTimeout (timers.js:133:15)

It seems like incidentController is/becomes undefined somehow. Can someone explain why this is expected behavior (I assume it is, anyway)?

I can work around this pretty easily, but I'm just curious why it behaves this way -- makes passing in parameter values a bit less convenient since I can't do it inside the setInterval statement itself.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Russell Christopher
  • 1,677
  • 3
  • 20
  • 36
  • 1
    because you are executing the function! :) It has no clue you want to assign a reference to it. – epascarello May 24 '15 at 03:10
  • 1
    [Pass parameters in setInterval function](http://stackoverflow.com/questions/457826/pass-parameters-in-setinterval-function) / [How can I pass a parameter to a setTimeout() callback?](http://stackoverflow.com/questions/1190642/how-can-i-pass-a-parameter-to-a-settimeout-callback) – Jonathan Lonowski May 24 '15 at 03:13

2 Answers2

7

setInterval accepts a function object as the first parameter. But, when you do

setInterval(incidentController(123), 10 * 1000);

you are passing the result of invoking incidentController, which is undefined (In JavaScript, if a function doesn't return anything explicitly, then by default, undefined will be returned). That is why you are getting the error

Cannot read property 'apply' of undefined

It is trying to invoke the apply function on undefined.


makes passing in parameter values a bit less convenient since I can't do it inside the setInterval statement itself

No, sir. You can conveniently pass the parameter to the callback function in setInterval itself, like this

setInterval(incidentController, 10 * 1000, 123);

Now, when incidentController is invoked, after every 10 seconds, 123 will be passed as the first parameter to it.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • 1
    did not know that syntax setInterval(incidentController, 10 * 1000, 123);. Is it documented ? –  May 24 '15 at 03:14
  • 2
    @maboiteaspam Yup, its documented in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval#Syntax), and also in [Node.js docs](https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_arg) – thefourtheye May 24 '15 at 03:15
  • Whoa, didn't know about that either, that's cool. I guess that's a recent feature? At the bottom it says IE10+ for callback parameters support. –  May 24 '15 at 03:16
  • 1
    @AlfonsoGarnett Most browsers don't support that yet. But OP has tagged node.js. So, it would work very well for him :-) – thefourtheye May 24 '15 at 03:25
1

It is incorrect to use setInterval like

setInterval(incidentController(123), 10 * 1000);

because it expects a function as the first parameter(not an executed function with a result).

If you wish to pass a parameter to the call back, you should wrap the function call with an anonymous function like

setInterval(function(){incidentController(123)}, 10 * 1000);

See Pass parameters in setInterval function

Community
  • 1
  • 1
AmmarCSE
  • 30,079
  • 5
  • 45
  • 53