1

I've looked at related questions and none have helped me. I am therefore creating this question.

So my client decrypts URLs and sends them to my server, which then decrypts them and makes an API call using the decrypted request. On the server side everything seems to be working fine. No errors are being thrown. Logs seem fine etc.

My AJAX looks like:

var handleRequest = function(request){
    $.ajax({
        type: "GET",
        url: host + '/requests?call=' + request,
        success: function(data) {
        var rawJSON = JSON.stringify(data, null, 2);
        console.log('Recieved: ' + rawJSON);
        editor.setValue(rawJSON);
       },
       error: function(jqXHR, responseText,status){
            console.log(jqXHR.responseText)
       },
       dataType: 'jsonp'
    });
}

Server side:

app.get('/requests', function(req, res) {
    var call = req.query.call;
    var decryptedRequest = decryptRequest(call);
    console.log("Recieved: " + decryptedRequest);

    var rawJson = retriever.makeExternalCall(decryptedRequest);
    console.log('Sending response to client');

    res.setHeader('Content-Type', 'application/json');
    res.send(rawJson);
});

Method used above:

var requestService = require('request');

module.exports = {
    makeExternalCall: function(url) {
        console.log('Making call to: ' + url);
        requestService(url, function(error, response, body){
            console.log(body);
            return body;
        });
    }
}

Strangely when I replace

res.send(rawJson);

with

res.send('hello');

I get a response. Any ideas on what is going on here?

Mr Spartacus
  • 127
  • 1
  • 10
  • 2
    The `makeExternalCall` function doesn't return anything. Which means `rawJson` is undefined. This is an extremely common issue: http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call –  Jan 27 '17 at 21:06
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) –  Jan 27 '17 at 21:07
  • Hmmm that was an issue I had already though I addressed @ChrisG . I am not from a functional programming background so this is a rookie mistake on my part. I guess I can just return the function? – Mr Spartacus Jan 27 '17 at 21:08
  • (The solution is to move `res.send()` to where you currently have `return body;`) –  Jan 27 '17 at 21:08
  • Isn't it good practice to send a response in the request handler. i.e. app.get(.....)? – Mr Spartacus Jan 27 '17 at 21:10
  • probably your `requestService` haven't returned the response yet but your code already called `res.send(rawJson)`. That's how asynchronous calls work. – Roljhon Jan 27 '17 at 21:11
  • @MrSpartacus Yes it is, but not if it's impossible to do so. That's simply how node.js works. It's all asynchronous and callbacks. Did you not read the page I linked? –  Jan 27 '17 at 21:13
  • If you try to set a timeout enough to wait for the response, that might also work before it fires `res.send(rawJson)`, – Roljhon Jan 27 '17 at 21:15
  • Sorry I will have a proper read of that now @ChrisG . Thanks for the help. – Mr Spartacus Jan 27 '17 at 21:16

1 Answers1

2

The function makeExternalCall is an async function. Returning from callback doesn't work as the async function has already returned before returning the data and hence rawJson is undefined.

Solution to this is proper usage of the callback.

var requestService = require('request');

module.exports = {
    makeExternalCall: function(url,callback) {
        console.log('Making call to: ' + url);
        requestService(url, callback);
    }
}

And then in API handler

app.get('/requests', function(req, res) {
    var call = req.query.call;
    var decryptedRequest = decryptRequest(call);
    console.log("Recieved: " + decryptedRequest);

    retriever.makeExternalCall(decryptedRequest, function(error, response, body) {
        if (error) {
            res.send("error message");
        } else {
            res.setHeader('Content-Type', 'application/json');
            res.send(body);
        }
    })
});
bibek shrestha
  • 448
  • 3
  • 9