javascriptgoogle-maps-react

Google Maps Directions Service, How to wait for all requests to finish?


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!


Solution

  • 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.