I have a list of technicians that I need to get individual drive times between a certain location. I have been using a script to do this within Google Sheets
but I would rather do the computation within my web application instead. There are of course a few issues here. One is that I can't just make these requests within a for loop without having some sort of delay, or else I will get an over_query_limit
error. The other issue is that I want a way to let the user know that all requests have finished, and that is the part I'm stuck on. I'm currently using the google-maps-react
npm package to accomplish this.
Here is what I currently have:
TechDriveTimeTest(techs, kioskInfo){
let result = []
techs.forEach(tech => {
if(tech.Address != "" && !tech.Notes.includes('Not')){
result.push(tech);
}
})
//console.log(result);
let directionsService = new google.maps.DirectionsService();
result.forEach((tech, index) => {
let techAddress = tech.Address + " " + tech.City + " " + tech.State + " " + tech.Zip
let req = {
origin: techAddress,
destination: 'some destination',
travelMode: 'DRIVING'
}
this.GetTime(index, req, directionsService);
})
}
GetTime(i, req, service){
setTimeout(function(){
service.route(req, function(res, status){
if(status == 'OK'){
let time = res.routes[0].legs[0].duration.text
console.log(time);
}
})
}, (i+1) * 1000)
}
This code works fine with delaying the requests so that I don't receive an error anymore, but it would be nice to know when all of the requests are finished so I can notify the user. Thanks!
You can use recursion to run the requests one at a time, here is an example:
function TechDriveTimeTest(techs, kioskInfo){
techs = techs.filter(tech => tech.Address != "" && !tech.Notes.includes('Not'))
.map(tech => `${tech.Address} ${tech.City} ${tech.State} ${tech.Zip}`);
const directionsService = new google.maps.DirectionsService();
recursion();
function recursion() {
const techAddress = techs.shift();
directionsService.route({
origin: techAddress,
destination: 'some destination',
travelMode: 'DRIVING'
}, function(res, status){
if(status == 'OK'){
let time = res.routes[0].legs[0].duration.text
console.log(time);
}
if (techs.length) {
setTimeout(recursion, 1000);
} else {
console.log('DONE');
}
});
}
}
Here, the recursion
removes the first element from the techs
array and then, when the directions response comes in, if there are still elements in the techs
array, the recursion
function is called again.