0

I have this example array

[{
  "car": "Toyota",
  "ID": "1",
  "Doors": "4",
  "price": "0"
}, {
  "car": "Chevrolet",
  "ID": "2",
  "Doors": "2",
  "price": "0"
}, {
  "car": "Dodge",
  "ID": "3",
  "Doors": "2",
  "price": "0"
}]

How can I do a request for all ID in array, and the results of all IDs return it in the array price.

request(
  'http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+ID,
  function (e, r, body){
    var req_data = JSON.parse(body);
  }
)

Thank you!

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
Matias Rodriguez
  • 35
  • 1
  • 1
  • 7

2 Answers2

4

You can use async.map to do this. Using your code as a starting point it might look like this (I changed the URL to a site that I know echoes JSON):

var request = require('request');
var async = require('async');
var data = [{
              "car": "Toyota",
              "ID": "1",
              "Doors": "4",
              "price": "0"
            }, {
              "car": "Chevrolet",
              "ID": "2",
              "Doors": "2",
              "price": "0"
            }, {
              "car": "Dodge",
              "ID": "3",
              "Doors": "2",
              "price": "0"
            }];

async.map(data , function(item, callback) {
  request("https://randomvictory.com/random.json?id="+item.ID,
           function(error, response, body) {
             if(!error) {
               //having checked there was no error, you pass 
               //the result of `JSON.parse(body)` as the second
               //callback argument so async.map can collect the
               //results
               callback(null, JSON.parse(body));
             }
           });
}, function(err, results) {
  //results is an array of all of the completed requests (note
  //that the order may be different than when you kicked off
  //the async.map function)
  console.log(err, results);
});
Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
1

You can use any of the interface wrappers recommended by request and Promise.all(). For example, using native promises and following this example:

const request = require('request-promise-native')

Promise.all(array.map(({ ID }) => request({
  uri: `http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name=${ID}`,
  json: true
})).then(data => {
  // each of the response objects in the same order as initial array
  data.forEach(objRes => console.log(objRes))
}).catch(error => {
  // handle the first rejected error here
})
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • Very clean, but I'm curious, is the order of the requests maintained? I would assume async would not offer that guarantee, is promise-native calling synchronously or is it reordering the results to preserve order? – Jason Sperske Jul 18 '17 at 18:04
  • @JasonSperske see the documentation I linked for `Promise.all()`. It does maintain the same order, [as per the specification](http://www.ecma-international.org/ecma-262/6.0/#sec-promise.all-resolve-element-functions). – Patrick Roberts Jul 18 '17 at 18:04
  • 1
    An interesting side effect of this answer is you will only get the final results collection if all requests successfully complete, if that is the behavior you are looking for then this is the best answer. – Jason Sperske Jul 18 '17 at 18:08
  • @JasonSperske I added the usage for that in the example. Also if you didn't see I linked in my above comment where the order of `Promise.all()` is preserved in the specification. – Patrick Roberts Jul 18 '17 at 18:14
  • 1
    It already had my up vote :) I was just pointing out that if any error occurs (like one of the HTTP requests failing) will cause `Promise.all` to jump to the error callback (which could be exactly what the OP is looking for) – Jason Sperske Jul 18 '17 at 18:20