-3

After I create a javascript object and convert it to json my object is not fully converted.

Create javascript object.

var inputData = {
    "StartDate": moment(startDate).format('YYYY[-]MM[-]DD'),
    "EndDate": moment(endDate).format('YYYY[-]MM[-]DD'),
    "AllRates": []
};

Fill array with objects received from API.

for (var i = 0; i < dates.length; i++) {
    $.getJSON(
        "http://api.fixer.io/" + dates[i] + "?base=USD", 
        function (data) {
            inputData.AllRates.push(data);
        }
    );
}

I get an object that looks like this: console.log(inputData);

But when I convert an object into json by JSON.stringify() I get an empty array:

{"StartDate":"2017-07-10","EndDate":"2017-07-13","AllRates":[]}
robinCTS
  • 5,746
  • 14
  • 30
  • 37
  • 2
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Yury Tarabanko Jul 30 '17 at 09:33

1 Answers1

1

You are probably converting the object to JSON before the data from the requests arrived and your inputData.AllRates.push(data) callback got called. You have to keep track how many responses arrived and convert to JSON only after the last one arrived:

var dateCount = dates.length;
var finished = 0;
for(var i = 0; i < dateCount; i++){
  $.getJSON("http://api.fixer.io/" + dates[i] + "?base=USD", 
    function(data){
      inputData.AllRates.push(data);
      if(++finished === dateCount){
        console.log(JSON.stringify(inputData));
      }
    });
}
Stephan
  • 2,028
  • 16
  • 19
  • You'd still want to do something after retrieval completion (besides logging), so I would look into [`Promise.all()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) ^^ – moonwave99 Jul 30 '17 at 09:25
  • You could still call a custom callback instead of just logging. I would definitely use `Promise.all` if the AJAX function would return a Promise (or if using for example the fetch API instead), but in that situation I am not sure if it wouldn't get more complex by partly using promises. – Stephan Jul 30 '17 at 09:28
  • Thank you, this solution works) But the JSON.stringify(inputData) is called after the loop and the data from API was inside the object, which means inputData.AllRates.push(data) callback got called? – Евгений Иванов Jul 31 '17 at 11:44
  • `inputData.AllRates.push` runs every time a response arrives, `JSON.stringify` only when the last one arrives and thus all rates have been stored already. – Stephan Jul 31 '17 at 12:38