The saga of Arrow functions with callback functions

The saga of Arrow functions with callback functions

Hi everyone! I hope you are doing well, I am back with another article this time, this was kind of one topic that was pending from this blog.

Let me reintroduce you guys, people usually say that one should use the arrow function with the callback functions and they give the following example, they will ask you the output of the following code --

const me = { 
 fName:"Mihir",
 /* Tradional function only, 
  * you can write tradional function inside a obj 
  * like this
  */
 talk() {
  setTimeout(function (){ 
   console.log(this.fName)
   },0)
 }
}
me.talk()

Screenshot 2022-01-29 at 9.03.54 PM.png

You know the output, but if you don't know you need to seriously check this blog.

To fix this what next? You know this. Yes, you are right. You need to do

const me = { 
 fName:"Mihir",
 /* Tradional function only, 
  * you can write tradional function inside a obj 
  * like this
  */
 talk() {
  setTimeout(()=> { 
   console.log(this.fName)
   },0)
 }
}
me.talk()

Screenshot 2022-01-29 at 9.05.32 PM.png

So, yeah then people say, I should definitely use arrow functions with callback functions.

Here's one more example in that case -

document.body.addEventListener("click", function() { 
 console.log(this) // You get the body element
})

Screenshot 2022-01-29 at 9.06.52 PM.png

But if you do the same with the arrow function it won't work.

To understand this refer to blog, (I know I am quoting this a lot, but please bear with me).

Then you will say, bro? Event Handlers are also callback functions, which I addressed in that blog as well. So the million-dollar question is when to use arrow functions with callbacks and when not to use them.

To answer all of this, I will say it " depends ", it depends on how the functions are working under the hood, to understand when to use and not to use you need to check the implementation, which is not possible every time, and I don't consider this as any gotcha, I consider this as a design decision. I don't know the design name, but I will show you a basic implementation.

function outer(cb,obj){
 cb()
}

function inner(){
 console.log(this.fName)
}

outer(inner,{fName:"Mihir"})

Screenshot 2022-01-29 at 9.10.39 PM.png

If you need to understand how that resolved to undefined, you need to check this blog.

If you want to get the correct this.fName as Mihir, you need to bind the function call to the inner function, you can do it using call, bind, apply. I will use call.

function outer(cb,obj){
 cb.call(obj)
}

function inner(){
 console.log(this.fName)
}

outer(inner,{fName:"Mihir"})

Screenshot 2022-01-29 at 9.12.11 PM.png

Woohoo! You get the desired output. So moral of the story

Inner function resolving the desired value of this depends on how the outer function is handling the inner function. So inside the event listener, under the hood, all these nitty-gritty details are handled, or maybe some other complex logic, but the gist is somewhat this only and you should consider this as a design pattern. Event handlers are designed like this and therefore we should not use arrow functions with them.

I hope you got the value out of this blog. Thank you for reading this until here. Bye and Peace!