1

I am looking to get the data from 2 json files every 60 seconds. One file contains news articles, and the second file contains comments relating to each article.

I can download the comments for updates every 60 seconds, and pass the json to the results function.

function updateData() {

 var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");

 xobj.onreadystatechange = function () {
      if (xobj.readyState == 4 && xobj.status == "200") {
        //showResults(xobj.responseText);
        showResults(JSON.parse(xobj.response));
      }
 };

 xobj.open("GET", "comments.json", true);
 xobj.send();

 setTimeout(updateData, 60000);
}

However, how do I open 2 json files, and pass the results to the showResults function using the callback?

I am trying to display the topics and comments together. So for each topic, get the comments for that topic. I can get this working by using globals, but I think that is a poor approach.

  xobj.onreadystatechange = function () {
    if (xobj.readyState == 4 && xobj.status == "200") {
    topics = JSON.parse(xobj.response);
    }
  };

  xobj2.onreadystatechange = function () {
    if (xobj2.readyState == 4 && xobj2.status == "200") {
    comments = JSON.parse(xobj2.response);
  }
 };

I saw a solution that downloaded multiple json files, but then we do not know what file would download first, so I would be unable to use:

showResults(JSON.parse(xobj.response), JSON.parse(xobj2.response));

Because it is asynchronous, and the order could differ, and showResults would need to expect the order to be (topics, comments).

I am looking for a way that the current function can have access to the data from both of the files.

 function showResults(json) {
 // Have both here to display
 }

Is using globals acceptable?

1 Answer 1

1

You want to use Promise.all to combine the two promises that you get from reading the two files. This will give you a new promise that resolves when both of the other promises are ready, and it will resolve with an array of both promises' results.

For instance:

const combinedPromise = Promise.all([readFile1(), readFile2()]);
combinedPromise.then(([file1, file2]) => // ... code that uses both files
Sign up to request clarification or add additional context in comments.

4 Comments

Can I be assured the order of the results? Thanks for the comment. I added fetch to get the data to take advantage for promises. Promise.all([ fetch("../downloads/news.json"), fetch("../downloads/comments.json")]) . I then call .then(function (data) { showResults(data) }); In showResults I use data[0] to get news data, and data[1] to get comments data. This is working, but my fear is the order. Will data[0] always be news, and data[1] always be the second file?
Yes, the order is fixed: whatever order you give the arguments to Promise.all is the same order as the results in the first .then chained to the resulting promise. But don't take my word for it ;) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… has a full explanation of Promise.all, and it confirms what I'm saying about the order.
Also don't forget that you can use destructuring here, so instead of making a showResults function like data => { use(data[0]); use(data[1]); } you can simply destructure the two parts of data in the arguments, ie. ([newsData, commentData]) => { use(newsData); use(commentData); }
Oh and also, if I answered your question, please do check the checkmark for it to indicate as much :)

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.