0

I am looping through an array containing a number of objects and for each object I want to make a fetch which should return a time prediction based on information about the current object. I then want to add this time to a time variable that is declared outside the loop. In the example below I have two objects in the array. The first object returns a time of 34 and the second object returns a time of 72. However, when I check the time it is always only 72. Because of this I think the first might not be completing before the second one starts. The code looks as follows:

for (var l = 0; l < journeyArr.length; l++){
                        console.log("time at start of loop: ", time)
                        startStop = journeyArr[l].stops[0].id
                        endStop = journeyArr[l].stops[journeyArr[l].stops.length - 1].id 
                        routeid = journeyArr[l].routeid
                        lineid = journeyArr[l].lineid
                        fetch("http://localhost:8000/routes/api/predict/?lineid="+lineid+"&start_stop="+startStop+"&end_stop="+endStop+"&routeid="+routeid+"&time_secs="+seconds+"&temp="+temp+"&rain=0.16&dow="+dayNum)
                        .then(response => {
                            return response.json()
                        })
                        .then(data => {
                            time += data.journey_info.journey_time.hours * 60
                            time += data.journey_info.journey_time.minutes
                        })
                    }
                    //Timeout just after the for loop to fetch times and to calculate
                    setTimeout(()=>{
                        var hours = Math.floor(time / 60);  
                        var minutes = time % 60;
                        timeLeft.innerHTML = hours + " hour(s) " + minutes + " minutes";
                     },10000)
Ronan Byrne
  • 237
  • 2
  • 3
  • 9
  • Use RxJS merge. – JWP Aug 09 '20 at 12:25
  • This question may help you https://stackoverflow.com/questions/35612428/call-async-await-functions-in-parallel – ak85 Aug 09 '20 at 12:37
  • You have parts in your code (and comments) that seem unrelated to your question. Please only provide code to reproduce your problem, but not more than that. – trincot Aug 09 '20 at 12:39
  • 1
    You've tagged your question with `async`/`await` already, why are you not using it in your code? It's the solution! – Bergi Aug 09 '20 at 12:51
  • I am not too sure how to use `async/await` in this case although I do realise that it is likely the solution. – Ronan Byrne Aug 09 '20 at 12:57
  • 1
    Use it instead of the `then` calls, e.g. `const response = await fetch(…);` and then `const data = await response.json();` – Bergi Aug 09 '20 at 14:28

2 Answers2

1

You can use async/await in this case. Put your code inside an async function, and trigger fetch by calling the function.

let fetchData = async () => {
    let time = 0;
    for (var l = 0; l < journeyArr.length; l++){
        console.log("time at start of loop: ", time)
        startStop = journeyArr[l].stops[0].id
        endStop = journeyArr[l].stops[journeyArr[l].stops.length - 1].id 
        routeid = journeyArr[l].routeid
        lineid = journeyArr[l].lineid
        const response =  await fetch("http://localhost:8000/routes/api/predict/?lineid="+lineid+"&start_stop="+startStop+"&end_stop="+endStop+"&routeid="+routeid+"&time_secs="+seconds+"&temp="+temp+"&rain=0.16&dow="+dayNum)
        const data = response.json()
        time += data.journey_info.journey_time.hours * 60
        time += data.journey_info.journey_time.minutes
    }
    //Timeout just after the for loop to fetch times and to calculate
    setTimeout(()=>{
        var hours = Math.floor(time / 60);  
        var minutes = time % 60;
        timeLeft.innerHTML = hours + " hour(s) " + minutes + " minutes";
    },10000)
}

fetchData() // Trigger the fetch loop
samhoooo
  • 176
  • 10
-1

You have to declare your Variables in the for loop, otherwise you overwrite their values all the time and only have the last one.

so replace:

startStop = journeyArr[l].stops[0].id
endStop = journeyArr[l].stops[journeyArr[l].stops.length - 1].id 
routeid = journeyArr[l].routeid
lineid = journeyArr[l].lineid

with :

const startStop = journeyArr[l].stops[0].id
const endStop = journeyArr[l].stops[journeyArr[l].stops.length - 1].id 
const routeid = journeyArr[l].routeid
const lineid = journeyArr[l].lineid
Andre
  • 458
  • 5
  • 10