0

I have this code, I want to do a request() for each object in an Array. I think in something like this. But it doesn't works.

  var arrayLength = Temporal.length; //Temporal it's the name of the array
  for (var i = 0; i < arrayLength; i++) {
    var id = Temporal[i].market_hash_name;
    request('http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+id,
      function (e, r, body){
        var req_data = JSON.parse(body);
        var lowPrice = req_data['lowest_price'];
        Temporal[i].price = lowPrice;
      }
    );
  }

What I mean with that it doesn't work is that I would like for each market_hash_name I would like to saving the request into the same array but in price but I don't know how to do it, the code up is an idea

The array is this. Thanky you!

[{
  "market_hash_name": "Gamma Case",
  "price": "0",
}, {
  "market_hash_name": "Glove Case",
  "price": "0",
}, {
  "market_hash_name": "Chroma 2 Case",
  "price": "0"
}]
Elvis Ramirez
  • 23
  • 1
  • 1
  • 6
  • What does "it doesn't works" mean? What are you expecting the result to be? What do you observe the result to be? What exact problem do you want help with? – jfriend00 Jul 19 '17 at 00:35
  • Since it looks like you may be fairly new here, in the future, "it doesn't work" is not the sign of a good question here on stackoverflow. You should describe how you expect it to work, you should describe what you observed happening that was not that, you should describe what debugging steps you've taken to understand what is going on and then be very specific about exactly what you want help with. – jfriend00 Jul 19 '17 at 00:41
  • Edited///////// – Elvis Ramirez Jul 19 '17 at 01:25
  • your code should work but your `price` key will be filled asynchronously. you should wait for all responses in order to get your array filled completely. – guijob Jul 19 '17 at 01:43

3 Answers3

0

It's not clear exactly what problem you've observed, but I can see already that:

Temporal[i].price = lowPrice;

will not work because the request() callback is called sometime in the future, long after your for loop has finished and i is sitting on a value at the end of your array. The simplest change is to use .forEach() to iterate your array rather than the for loop:

  Temporal.forEach(function(item, i) {
    var id = item.market_hash_name;
    request('http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+id, function (e, r, body) {
        var req_data = JSON.parse(body);
        var lowPrice = req_data['lowest_price'];
        item.price = lowPrice;
      }
    );
  });

In a current version of node.js, you could also use a for loop with let i instead of var i or you could use a for/of loop.

For more info on this general issue and the options available, see:

Asynchronous Process inside a javascript for loop


If you also want to know when all the request() async operations are done, then there are a bunch of ways to do that. Without rewriting your code any further, you could just add a count.

  let requestsDone = 0;
  Temporal.forEach(function(item, i) {
    var id = item.market_hash_name;
    request('http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+id, function (e, r, body) {
        var req_data = JSON.parse(body);
        var lowPrice = req_data['lowest_price'];
        item.price = lowPrice;
        ++requestsDone;
        // check to see if all requests are done
        if (requestsDone === Temporal.length) {
            // here, you know that all requests are done and you can
            // use that result in here
        }
    );
  });

FYI, you also need error handling on your request() operations.

A more sophisticated method of tracking when all your requests are done is to use the request-promise module instead of request and then use Promise.all(). You can see how that works here:

Synchronized multiple API calls

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Added info about knowing when all the requests are done. – jfriend00 Jul 19 '17 at 01:55
  • @ElvisRamirez - Does this answer your question? If so, you can indicate that to the community by clicking the green checkmark to the left of the answer and that will also earn you some reputation points. – jfriend00 Aug 18 '17 at 06:18
0

i recommend you to use npm module called axios it easy
first download the module by typing:

npm install axios --save

then to request each of the array of object use this :

var axios=require('axios')
var array=Temporal
array.forEach(function(data){
 axios.get('http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+data.market_hash_name)
.then(function(body){
 data.price=body.data.lowest_price
 })
})
  setTimeout(function(){
console.log(array)      
 },1000)
0

You are doing an asynchronous operation inside each iteration of the for loop, when each operation callback is executed (the one you pass to request(url, callback)) the loop is already over.

Using forEach() at least will update the Array, but the execution is going to continue before it is updated (the asynchronous operations are still running). Which is not desirable behavior if you want to use the result after the loop.

I recommend you use Promises or some library for asynchronous control flow (like async).

Example using each()

var each = require('async/each');

async.each(Temporal, function(element, done) {
  var id = element.market_hash_name;
  request('http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+id,
    function (e, r, body) {
      var req_data = JSON.parse(body);
      var lowPrice = req_data['lowest_price'];
      Temporal[i].price = lowPrice;
      done();
    }
  );
}, function (err) {
  // continue execution here, at this point all the operations are done
});

In case you want to go with Promises, the learning curve is more elevated than going with callbacks, but it's worth learning how to use them. If you need an example with Promises let me know.

Antonio Val
  • 3,200
  • 1
  • 14
  • 27