Sunday, 17 September 2017

javascript - Returning a value from callback function in Node.js




I am facing small trouble in returning a value from callback function in Node.js, I will try to explain my situation as easy as possible. Consider I have a snippet, which takes URL and hits that url and gives the output:



urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {                              

var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
});


I tried to wrap it inside a function and return a value like this:



function doCall(urlToCall) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;

finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}


Because in my Node.js code, I have a lot of if-else statement where value of urlToCall will be decided, like this:



if(//somecondition) {
urlToCall = //Url1;

} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}


The thing is all of the statements inside a urllib.request will remain same, except value of urlToCall. So definitely I need to put those common code inside a function. I tried the same but in doCall will always return me undefined. I tried like this:



response = doCall(urlToCall);

console.log(response) //Prints undefined


But if I print value inside doCall() it prints perfectly, but it will always return undefined. As per my research I came to know that we cannot return values from callback functions! (is it true)? If yes, can anyone advice me how to handle this situation, as I want to prevent duplicate code in every if-else blocks.


Answer



Its undefined because, console.log(response) runs before doCall(urlToCall); is finished. You have to pass in a callback function aswell, that runs when your request is done.



First, your function. Pass it a callback:



function doCall(urlToCall, callback) {

urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return callback(finalData);
});
}


Now:




var urlToCall = "http://myUrlToCall";
doCall(urlToCall, function(response){
// Here you have access to your variable
console.log(response);
})


@Rodrigo, posted a good resource in the comments. Read about callbacks in node and how they work. Remember, it is asynchronous code.


No comments:

Post a Comment

casting - Why wasn't Tobey Maguire in The Amazing Spider-Man? - Movies & TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...