Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a value from callback function in Node.js [duplicate]

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.

like image 929
Pradeep Simha Avatar asked Apr 28 '14 11:04

Pradeep Simha


People also ask

Can a callback function return a value?

A callback function can return a value, in other words, but the code that calls the function won't pay attention to the return value. Yes, it makes fun sense to try and return a value from a promise callback.

How do you return a callback function?

We create a new promise, an object that will be returned from our callback using the new Promise() function. We invoke a . then() function on our promise object which is an asynchronous function and passes our callback to that function. That callback function takes in two parameters, a resolve, and a reject.

How do you repeat a function in node JS?

You use repeating to print repeating strings: const repeating = require('repeating'); console. log(repeating(100, 'unicorn '));


2 Answers

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.

like image 164
aludvigsen Avatar answered Oct 12 '22 22:10

aludvigsen


I am facing small trouble in returning a value from callback function in Node.js

This is not a "small trouble", it is actually impossible to "return" a value in the traditional sense from an asynchronous function.

Since you cannot "return the value" you must call the function that will need the value once you have it. @display_name already answered your question, but I just wanted to point out that the return in doCall is not returning the value in the traditional way. You could write doCall as follow:

function doCall(urlToCall, callback) {     urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {                                       var statusCode = response.statusCode;         finalData = getResponseJson(statusCode, data.toString());         // call the function that needs the value         callback(finalData);         // we are done         return;     }); } 

Line callback(finalData); is what calls the function that needs the value that you got from the async function. But be aware that the return statement is used to indicate that the function ends here, but it does not mean that the value is returned to the caller (the caller already moved on.)

like image 29
Hector Correa Avatar answered Oct 12 '22 22:10

Hector Correa