1

I'm using Express.js as middleware for my application. My frontend application calls an express route every couple of seconds with different parameters. The route then makes calls for each parameter to an 3rd party api. Inside each of these calls data is added to an array. After the for loop i send the the array back to the frontend.

I declare the array inside the route but the returned result is empty. When I declare the array outside the route it is working, but this is not optimal when multiple requests are made at the same time.

server.js

app.get('/prices',  function(req, res){

//array for holding all feeds
var feedData = [];

//Url params
var target = req.param('target');

//Convert the params to an array
var targetArray = target.split(',');

//Loop through targets and do request
for (var i = 0; i < targetArray.length; i++) {

   //API endpoint
   var url = xxx;
   request(url, function (error, response, body) {

     //Parse the XML body to javascript objects or json
     parseString(body, function (err, result) {


     //Store result in js object
     var resultObject = result;
     var arrayObject  = resultObject.quotes.quote;

     feedData.push(arrayObject[0])

   });

 });
}
console.log(feedData);
res.send(feedData);

//Clear feedData
feedData = [];


});

So bottom line is that the array is empty. Any suggestions?

0

2 Answers 2

3

You're being bitten by the async nature of node js (well, Javascript)

The call to request is asynchronous, and accepts a callback, but you're skirting over it, so your final console.log(feedData); etc... call is called before the callback of request is called.

Take a look at the async module, in particular eachSeries

A non-tested example of your code, using the async library:

app.get('/prices', function(req, res) {

  //Url params
  var target = req.param('target');

  //Convert the params to an array
  var targetArray = target.split(',');

  //array for holding all feeds
  var feedData = [];

  async.eachSeries(targetArray, function(targetArrayItem, cb) {

      request(url, function(error, response, body) {
          //Parse the XML body to javascript objects or json
          parseString(body, function(err, result) {


              //Store result in js object
              var resultObject = result;
              var arrayObject = resultObject.quotes.quote;

              feedData.push(arrayObject[0])

              //call the callback to iterate next item in targetArray
              cb();
          });
      });

  }, function(err) {
      //all done

      console.log(feedData);
      res.send(feedData);

      //Clear feedData
      feedData = [];
  })
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I had feeling i was getting hit by the async-train, just couldn't figure it out. Makes sense now.
0

This is because javascript is asynchronous and you send data before it's ready, so you need check for last request response and return collected data.

app.get('/prices',  function(req, res){

//array for holding all feeds
var feedData = [];

//Url params
var target = req.param('target');

//Convert the params to an array
var targetArray = target.split(',');

//Loop through targets and do request
for (var i = 0; i < targetArray.length; i++) {

   //API endpoint
   var url = xxx;
   request(url, function (error, response, body) {

     //Parse the XML body to javascript objects or json
     parseString(body, function (err, result) {


     //Store result in js object
     var resultObject = result;
     var arrayObject  = resultObject.quotes.quote;

     feedData.push(arrayObject[0]);

     //If is last request return result
     if(i==targetArray.length-1){
          console.log(feedData);
          return res.send(feedData);
    }
   });

 });
}
});

1 Comment

This won't work, you're targetArray is outside the callback for request - and nothing iterates the for loop

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.