XyzCoder.com


Collection of my learnings - Pavan Kumar Aryasomayajulu

Callback Functions in JavaScript

Tags:

Hi,

In this post, I would like to write about Callback functions in Javascript. Callback functions play a major role in Javascript and used very extensively.


Is function an object in Javascript:

Yes, functions in Javascript are objects just like an array and other objects.


var myFunction= function(a){
	alert(a);
}

alert(myFunction instanceof Object); //This will alert true

When we say functions in javascript are objects. If that is the case then an object is supposed to have the ability to store properties. Yes, even javascript functions can have properties too.

var myFunction= function(a){
	alert(a);
}

myFunction.test ="Pavan";

alert(myFunction.test); // This will alert Pavan


Anonymus Functions:

Anonymus functions are just like any other functions but they will not have any name. But we will have function definition there itself.

In general, we define functions with names in the below manner


function printName(name){
    alert(name);
}

//Calling a function with name
printName("Pavan Kumar Aryasomayajulu");


Now let me create an anonymous function which alerts name and performs the same functionality as above one.


(function(name){
	alert(name);
})("Pavan Kumar");

The above code snippet consists of a function which alerts the name and if we closely observe, the function doesn't have any name. This is an anonymous function. 
Note: This way of writing function and executing it immediately is very well known as IIFE function.


But not every time we want to create a function and immediately execute the function right. So what we can do is create an anonymous function and assign it to a variable. If you have any experience with C#, this is somewhat similar to Delegates in C#.


var sumFunction = function(a,b){
return a+b;
}

alert(sumFunction(1,2));



If functions are objects can we pass them as parameters to other functions just like Array or string:

When I first learned that functions in javascript are objects for the first time, this was the question in my mind. The answer to this question is YES. Just like any other objects, functions can also be passed as a parameter to other functions in Javascript.

This way of passing functions to other functions and executing them is called callback function execution.


Let's see differents ways of passing callback functions


var add = function(a,b){
return a+b;
}

var sub = function(a,b){
	return a-b;
}


function Calculator(val1,val2,callback){
        // Assume there are many lines of business code.
	if(isNaN(val1) || isNaN(val2)){
		alert("please enter valid numbers")
	}
	else{
		var value = callback(val1,val2);
		alert(value);
	}
}

Calculator(1,2,add);


In the above code add and sub are 2 different functions. Calculator is my function which has business logic. So here I am passing variables on which I need to perform numerical operations. Along with that, i am also passing the function that is supposed to be executed. Here I am passing 1,2 and on these variables, I want to perform an add operation. So I am passing add function.


Another way of implementing callback functions is to simply pass an anonymous function as a parameter.




function Calculator(val1,val2,callback){
        // Assume there are many lines of business code.
	if(isNaN(val1) || isNaN(val2)){
		alert("please enter valid numbers")
	}
	else{
		var value = callback(val1,val2);
		alert(value);
	}
}

Calculator(1,2,function(a,b){
    return a+b;
});

If we see the above code, instead of creating an anonymous function and assigning it to a variable and passing that variable as a callback function, we are simply creating an inline function and passing it as a parameter.

Note: In most of the advanced javascript frameworks we follow this approach of creating anonymous functions and passing them as a callback function.


In the below code, I am creating an object and creating all the data I want to pass as properties including my callback function.


function Calculator(data){
        // Assume there are many lines of business code.
	if(isNaN(data.val1) || isNaN(data.val2)){
		alert("please enter valid numbers")
	}
	else{
		var value = data.callback(data.val1,data.val2);
		alert(value);
	}
}

Calculator({
	val1:1,
	val2:2,
	callback:function(a,b){
		return a+b;
	}
});


Why Callback functions:
In my above examples, I was explaining what callback functions are and how to create them. But we didn't  see where exactly we can use them in the real world. I'll provide a few use case where I use callback functions extensively.
Whenever we are using any JS frameworks , we are mostly using callback functions.

Providing end user ability to inject code:
Let's assume that I wrote a framework to make HTTP calls to my server from javascript(AJAX calls).
In my framework, I have only one file that is ajax.js. Now if I want to distribute my file to someone else, I need to provide the other party to inject some code or else I should provide them ability to edit my file. If we have less code then the person who is making use of my js code can edit my file and use it. But in reality these framework files will have complex code which is not suggestable to edit. Also in future if we want to upgrade the framework files to latest version, obviously we will loose our changes to the old file.

So the best way is to provide users flexibility to inject some code .In this example, if we are making an ajax call and obviously we want to execute our js code once the ajax call is successful. Here callback functions come to rescue us.

MySampleAjax.js
  1. function makeAjaxRequest(url,param,callback) {    
  2.             var xmlHttp;    
  3.             //Let us create the XML http object    
  4.             xmlHttp = null;    
  5.     
  6.             if (window.XMLHttpRequest) {    
  7.                 //for new browsers    
  8.                 xmlHttp = new XMLHttpRequest();    
  9.             }    
  10.             else if (window.ActiveXObject) {    
  11.                 var strName = "Msxml2.XMLHTTP"    
  12.                 if (navigator.appVersion.indexOf("MSIE 5.5") >= 0) {    
  13.                     strName = "Microsoft.XMLHTTP"    
  14.                 }    
  15.                 try {    
  16.                     xmlHttp = new ActiveXObject(strName);    
  17.                 }    
  18.                 catch (e) {    
  19.                     alert("Error. ActiveX disabled")    
  20.                     return false;    
  21.                 }    
  22.             }    
  23.     
  24.             if (xmlHttp != null) {    
  25.                 //Handle the response of this async request we just made(subscribe to callback)    

  26.                 xmlHttp.onreadystatechange = function () {    
  27.                     if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {    
  28.                         callback(xmlHttp.responseText);    //Here i am calling user injected callback function after the ajax request is success
  29.                     }    
  30.                 }    
  31.     
  32.                 //Pass the value to a web page on server as query string using XMLHttpObject.    
  33.                 xmlHttp.open("GET", url+"?userName=" + param, true);    
  34.                 xmlHttp.send();    
  35.             }    
  36.         } 
I'll make use of the above file

Login.html
<html>
<head>
    <script src="MySampleAjax.js">
</head>
<body>
    <script>
        var username ="pavanarya";
        
        makeAjaxRequest("login.aspx",username,function(result){
            //lets assume that my server returned a json string             var data = json.parse(result);             window.localstorage.userdata = data;
        });              </script> </body> </html>

So in this sample code , I am simply trying to call the makeAjax function defined in another file. When making that call I am simply injecting my js callback function which needs to be executed after the ajax call is successful.

If we take the case of Jquery we use callback functions almost 95% of the time. The same is the case with Node.js and other JS.

If you like my post and want to get my future posts to your email directly, please subscribe to my blog .


Thanks,

Pavan Kumar Aryasomayajulu



Comments Section:
Add Comment


  • Karthik

    Nice article pavan.

    Reply