Recently I was taking Node.js classes for company’s training batch. I was explaining about the code reusability & callback functions at that time. At that time came across an interesting problem due to the assignment I gave to them.
The assignment is simple. Search user with the name given, update the address of the user and print the user details after the update. Wanted to explain the power of callbacks so gave only one restriction. The function which is used for the searching user with the name given need to be used for printing the user details after the update.
No one finished the assignment. I heard their concerns, Almost all of them confused at the callback function level. The main problem is how we can pass a variable to the callback function because they need to use the same function at 2 places. So I told them will do it for you so that next time you won’t confuse.
I thought its a simple problem. I can write the program in a jiffy. So, I wrote code like this
After running this program got output like this
Connected {"employeeId":2,"employeeName":"Aditya","employeeAddress":"Delhi"} /Users/ashoktankala/Desktop/learning/Training/UpdateAddressOfAUser.js:28 if (err) throw err; ^ Error: Cannot enqueue Query after invoking quit. at Protocol._validateEnqueue (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/protocol/Protocol.js:203:16) at Protocol._enqueue (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/protocol/Protocol.js:138:13) at Connection.query (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/Connection.js:200:25) at /Users/ashoktankala/Desktop/learning/Training/UpdateAddressOfAUser.js:27:13 at Query.<anonymous> (/Users/ashoktankala/Desktop/learning/Training/UpdateAddressOfAUser.js:19:9) at Query.<anonymous> (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/Connection.js:502:10) at Query._callback (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/Connection.js:468:16) at Query.Sequence.end (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24) at Query._handleFinalResultPacket (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/protocol/sequences/Query.js:139:8) at Query.EofPacket (/Users/ashoktankala/Desktop/learning/Training/node_modules/mysql/lib/protocol/sequences/Query.js:123:8)
It totally blew my mind. How can my callback function(printEmployeeDetails) execute first than the function(updateEmpAddress) I called/wanted to call. Tried several things to solve but understood that I didn’t understand the concept of passing a variable to a callback function properly.
My experience always taught me It’s better to create a small example of our problem than solving on a Project or on a Program which does a couple of things.
So I wrote an example program like this to solve this problem or understanding the concept of passing a variable to a callback function.
var mainFunction = function(callback) { //Did something console.log("In Main Function"); callback(); } var callbackFunction = function() { console.log("In Callback Function"); } mainFunction(callbackFunction("Variable"));
I got below output
[Running] node "/Users/ashoktankala/Desktop/learning/test.js" In Callback Function In Main Function /Users/ashoktankala/Desktop/learning/test.js:3 callback(); ^ TypeError: callback is not a function at mainFunction (/Users/ashoktankala/Desktop/learning/test.js:3:2) at Object.<anonymous> (/Users/ashoktankala/Desktop/learning/test.js:10:1) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.runMain (module.js:604:10) at run (bootstrap_node.js:390:7) at startup (bootstrap_node.js:150:9)
So, It means if I pass a variable in the function which I want to use as a callback function will execute first and its return value considers as an argument for the main function. If I want to use a function as a callback function I should treat it(function) like a variable.
After googling came across this super article which explained the concept(“How to pass a Variable to a callback function”) beautifully.
bind() is going to be the saviour of our problem. Now I updated my example program like this
bind() creates a new function that will have the same body as the original function. this object of the new function will have the object that has specified in the initial parameters. Now the output is
In Main Function Variable: Variable In Callback Function
Ola! Problem solved.
Now the assignment program corrected. It’s become like this
Now the output is
Connected 1 record(s) updated {"employeeId":2,"employeeName":"Aditya","employeeAddress":"Delhi"}
Cool! Right? Oh, Node.js! You never stop to amaze me. Love you darling!
That’s it, guys. The movie is over. Happy Ending.
Peace. Happy Coding.