1

I have an array of elements through which I'am iterating and making some RPC calls to get the response, push the response into array and send it back to UI to display. But these responses are asynchronous and not getting pushed into array. So when the response is received at UI side, it is empty.

NodeJS code:

app.get('/getData/:obj', function(req,res, next){

    data = JSON.parse(req.params.obj);

    var options = ["location","start","end","user"];

    /*Data looks like this*/

    /*[ { start: '12-05-2016' },
      { end: '12-09-2016' },
      { location: [ 'US','UK' ] },
      { user: [ 'Jim','Jack' ] } ]*/

    var requestArray = [];
    for(var d in data) {
        if(options.indexOf(d) > -1 ) {
            var rpcRequest = {};
            rpcRequest[d] = data[d]
            requestArray.push(rpcRequest);
        }

    }
    console.log(requestArray);
    var resp = []

    for(var i in requestArray)    {
        var item = requestArray[i];
        _.each(item, function(value, key) {
            console.log('key :'+key+'\tvalue: '+value);
            if(util.isArray(value)) {
                for(var val in value)   {
                    var request = {};
                    request[key] = value[val];
                    console.log('\tkey :'+key+'\tvalue: '+value[val]);
                    console.log('request: '+JSON.stringify(request));

                    switch(key) {
                        case "location": 
                            rpcClient.location(request, function(err, response) {

                                response = (JSON.stringify(response)); //asynchronous  response

                                resp.push(response); //push response into array

                            });
                            break;
                        case "user":
                            rpcClient.user(request, function(err, response) {

                                response = JSON.stringify(response); //asynchronous  response

                                resp.push(response); //push response into array

                            });
                            break;

                        default: break;
                    }


                }
            }

        });

    }

    console.log(resp);
    res.send({d:resp}); // send the response array, but it is empty
}); 

How do I make the pushing of data into array synchronous or get the proper data in some way. I have heard of async module, nut not quite sure how to use it here.

Seeking help! Thank you :)

1

1 Answer 1

1

You wait to call res.send until the last response has been received.

So you keep track of how many responses you've received, and when you receive the last one, then you call res.send from within the response callback for that final response.

Here's a simplified example:

var requests = [
  "one", "two", "three", "four", "five"
];
var responses = [];
requests.forEach(function(request) {
  // setTimeout to get something async
  setTimeout(function() {
    // Now we're in the async operation callback
    var response = "Response for " + request;
    console.log("Got: " + response);
    
    // Save the response
    responses.push(response);
    
    // Is it the last one?
    if (responses.length == requests.length) {
      // We're done, this is where you'd do
      // `res.send`
      console.log("Done! Got all responses: ", responses);
    }
  }, Math.random() * 1000);
});


Side note: Don't use for-in to loop through arrays unless you're doing it on purpose because of a sparse array; that's not what it's for. See this question's answers for your various options for looping through arrays.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer! But I'm not sure about time that the response may take, so using a fixed timeout wouldn't help in my case.
@YajneshRai: I haven't suggested using a fixed timeout. The setTimeout in the above, as the comment says, is to emulate your async operations for the purposes of the example. You wouldn't really use setTimeout, you'd just do the same thing with your real async operations. The key is that you call res.send from within an async completion handler, when you've received all of the responses.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.