0

Folks, following bit of code does not return 'baz' properly. It says its undefined. Why?

getJSON = function(options, onResult)
{
    //console.log("rest::getJSON");
    var prot = options.port == 8443 ? https : http;
    var req = prot.request(options, function(res)
    {
        var output = '';
        console.log(options.host + ':' + res.statusCode);
        res.setEncoding('utf8');

        res.on('data', function (chunk) {
            output += chunk;
        });

        res.on('end', function() {
            var obj = JSON.parse(output);
            onResult(res.statusCode, obj);
        });
    });
    req.on('error', function(err) {
        //res.send('error: ' + err.message);
    });
    req.end();
};

exports.Search = function(req, res){
    if (!req.session.username) {
        res.redirect('/login');
    } else {

        options = {
            host: 'api.host.com',
            port: 443,
            path: '/ver/foo/'+req.body.bar,
            method: 'GET',
            rejectUnauthorized: false,
            requestCert: true,
            agent: false,
            headers: {
                'Content-Type': 'application/json'
                }
        };

        var baz = getJSON(options,function(statusCode, result) {
            console.log("onResult: (" + statusCode + ")" + JSON.stringify(result));
            // Check if User Exists
            status = JSON.stringify(result.Count)
            status = JSON.parse(status)
            if (status == 0) {
                res.render('foo/bar', { title: 'Title', Results: status, req: req });
            } else {
                results = JSON.stringify(result.Items)
                results = JSON.parse(results)
                name = results[0].name.S
                console.log("Found ",name)
                res.render('views/bar', { title: 'title', results: results, req: req });
            }
            baz = 'test';
            return baz;
        });
    }
 console.log(baz);
};
Cmag
  • 14,946
  • 25
  • 89
  • 140

1 Answers1

4

You can't return results from an async success handler like you are trying to do. The operation is asynchronous. It finishes LONG after the getJSON function has returned. Thus, there is no result to return when the getJSON function returns.

The getJSON call just STARTS the operation, then the getJSON call finishes executing and then sometime later, the getJSON call completes and your callback is executed. Returning a value from the callback function just goes into the bowels of the async infrastructure and is ignored. It does not go to your code anywhere.

The ONLY way to use an asynchronous result is to use the value in the success handler or call a function from the success handler and pass that function the data that you just received.

If you're going to use asynchronous networking calls, you have to program in an asynchronous fashion. This requires reworking the flow of your code and you cannot write code in a typical sequential fashion.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • thank you! I guess what I am trying to do here is return several API calls in one and render them. Will look at how I can bake them into the function – Cmag Dec 04 '13 at 15:43