1

I'm trying to fetch data from several urls stored in an array. Each url contains data in json format. I'm using a for loop to iterate over the urls stored in the url array. Each json file contains the travelTimeInSeconds value I'm interested in. When running the following code, the two values stored in the timeT variable are logged in the console. However, the ttTimes array remains empty. How do get the values to be stored in the ttTimes array?

urls = ['www.a.com/dataa.json','www.b.com/datab.json']
ttTimes = []

function getData(url) {
    fetch(url)
    .then(response=>{
        return response.json()
    })
    .then(data =>{
        let timeT = Math.round(data['routes'][0]['summary']['travelTimeInSeconds']/60); 
        console.log(timeT)
        ttTimes.push(timeT)
    })

}

for (url in urls){
    time = getData(urls[url])
    console.log(time)
    ttTimes.push(time)
};

6
  • 1. getData doesn't return anything 2. fetch is async, so even if you fix (1), time will contain a Promise, not timeT (which also isn't returned inside the callback) 3. to run multiple async functions, use Promise.all (this will return an array containing the results, exactly what you're looking for: jsfiddle.net/khrismuc/41axsLw6 Commented May 5, 2020 at 17:03
  • Note that: yes, you're not returning anything but instead pushing to ttTimes; but: while this works in theory, the requests runs at the same time and will finish a) in an unspecified order b) at some point in the future, long after the console.log(ttTimes) you probably have in your code somewhere Commented May 5, 2020 at 17:11
  • Thanks! Your solution also works. Is there a way to return ttTimes to be used in another function instead of just logging it to the console? Commented May 6, 2020 at 22:07
  • You can make the variable global again, but keep in mind that any function that uses it must be called after ttTimes has been set. Once you enter async, you cannot leave again. The idea is to put everything inside main, in order, and use await for async stuff. That way you can write "synchronous" code. I changed the above fiddle to show what I mean. Commented May 6, 2020 at 22:18
  • okay. Thanks. Is there a different way to get the data from the urls stored in the urls array that allows ttTimes to be returned and used in a new function? Commented May 6, 2020 at 22:28

1 Answer 1

1

The ttTimes array remains empty because you never wait for the promises to resolve before checking it. You could use Promise.all to wait for all of them before checking on the results array.

urls = ['www.a.com/dataa.json','www.b.com/datab.json']

// This function just returns a promise
function getData(url) {
  return fetch(url)
    .then(response=>{
      return response.json()
    })
    .then(data =>{
      const timeT = Math.round(data['routes'][0]['summary']['travelTimeInSeconds']/60); 
      return Promise.resolve(timeT);
    })
}


Promise.all(
  // use the urls to create an array of promises
  urls.map(getData)
).then((ttTimes) => {
  // When all the promises have been resolved, then this will be executed
  //Here all the promises have been resolved, so you would have an array with the ttTimes
  console.log(ttTimes);
})
Sign up to request clarification or add additional context in comments.

Comments

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.