Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a http.request returns undefined

I'm just starting out on Node.js. I have a basic question about a http.request. I want to write a JavaScript module with a couple of functions that return some data from a couple of servers.

Here's the code:

var mod = (function() {

    var my = {};
    var options = {
        hostname: 'example.com'
    };
    var foo = '';

    my.getBar = function() {
        var req = http.request(options, function(res) {
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
                // example.com returns JSON
                // TODO need to be able to get foo from outside this module
                foo = JSON.parse(chunk).bar;
            });
        });
        req.end();
    }
    return my;
}());

To get bar I do this:

console.log(mod.getBar());

but I get undefined. I think something asynchronous is happening.. get request happens, and while it is happening, I try and print the result which hasn't been received yet? I think I need to make it synchronous or something?

Many thanks.

like image 563
ale Avatar asked May 07 '13 09:05

ale


People also ask

Why is my code returning undefined?

A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .

Why Javascript console returns undefined?

A function without a return statement will return a default value. In the case of a constructor called with the new keyword, the default value is the value of its this parameter. For all other functions, the default return value is undefined .


1 Answers

If you look at getBar it doesn't return anything. That's why you get undefined. To get the result you'd have to send a callback to getBar:

getBar = function (callback){...

and call the callback with the result on end:

res.on('end, function(){
    callback(foo); 
});

Also I'd suggest you put foo inside getBar's closure in case you would do multiple requests at the same time. Likewise you should just concatenate the chunks on data and parse it on end, in case the response is too long for one chunk.

In the end your code should look like this:

var mod = (function() {

    var my = {};
    var options = {
        hostname: 'example.com'
    };

    my.getBar = function(callback) {
        var foo = '';
        var req = http.request(options, function(res) {
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
                foo += chunk;
            });
            res.on('end', function () {
                callback(null, JSON.parse(foo).bar); // The null is just to adhere to the de facto standard of supplying an error as first argument
            });
        });
        req.end();
    }
    return my;
}());

Get the bar like this:

mod.getBar(function(err, data) {
    console.log(data);
});
like image 167
Andreas Hultgren Avatar answered Sep 21 '22 13:09

Andreas Hultgren