Newbie question here.
I am trying to understand callback functions better. Reading about them here, i though i grasped the idea.
function greeting (name, callback){
console.log(`Greetings ${name}`);
callback();
};
function timeOfDay (time){
console.log(`How are you this fine ${time}?`);
};
greeting ('Brad', timeOfDay('evening') );
Output
How are you this evening?
Greetings Brad
Uncaught TypeError: callback is not a function
Can someone please explain why the output is in this order? What does this error refer to and why does it appear even though the code has finished?
I first did a simple callback function along the same structure and it worked fine.
Thanks in advance Brad
You were close, but when passing
timeOfDay("evening")
, you aren't actually passing that function as the callback. That is a function invocation and it runs immediately and whatever the return value of that is, is what is passed to thegreeting
function invocation as the second argument. SincetimeOfDay
doesn't return anything, you are passingundefined
togreeting
.The solution is to pass an actual function, not the result of invoking one (unless that result is, in fact, another function), to
greeting
, and one way we can do that is by wrapping thetimeOfDay()
function call in an anonymous function declaration, like this:Another technique is to use the
Function.bind()
method, which returns a copy of the function you've called it on, but the context that the function will execute in is configurable by you, based on the first argument you pass to.bind()
. This is a very useful technique, but requires a good knowledge and understanding of scope and context, which you can read more about in another answer of mine:As said in the comments, when you do something like this:
greeting ('Brad', timeOfDay('evening') );
you will be calling the
timeOfDay
function instantaneously.To avoid that you can use one of these options:
Wrap your function call in an anonymous function, like said in another answers.
You can omit/remove the parenthesis, like this
greeting('Brad', timeOfDay);
(this avoid instant function call, but you'll lose your parameter"evening"
and the error will persist).You can
.bind()
a context to the function, in the example below, I'm bindingthis
as the context to the function, that way it's not going to call the function instantaneously.take a look:
Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind