Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Running async functions simultaneously not updating state variable

I’m using ReactJS and trying to store the polyline returned by the Google Maps directions API in a state variable to be rendered conditionally later. This is the state variable that stores the first and second polylines:

const [routes, setRoutes] = useState({1: null, 2: null})

The problem is that when I update them through an asynchronous function, only the 2nd field updates for some reason

This is the function call

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    useEffect(() => {
        drawTaxiRoute(0, data.taxis, data.origin, data.map, setRoutes, routes)
        drawTaxiRoute(1, data.taxis, data.origin, data.map, setRoutes, routes)
    }, [])

And this is the async function (I removed the async keyword but it still behaves asynchronously due to the callback)

function drawTaxiRoute(N = 0, taxis, destination, map, setRoutes, routes) {
    ...

    directionsService.route(
        {
            origin: taxis[N].getPosition(),
            destination: destination,
            travelMode: google.maps.TravelMode.DRIVING,
        },
        function (result, status) {
            if (status == 'OK') {
                taxiRouteDisplay.setMap(map)
                setRoutes({...routes, [N+1]: result})
                console.log(result, N+1)
            }
        }
    )
}

According to the inspect element console, results is correctly returning the polyline, but the routes state is being incorrectly updated such that one is null:

{1: null, 2: {...}}

I suspect the issue is that routes is not updated in time for first time since it’s running in parallel so it’s still null when the 2nd async invocation starts and gets overwritten. Can anyone suggest a way to populate both polylines in route?

Thanks

>Solution :

The last call will overwrite the first, because when setRoutes is called, the value of routes is still the one passed on the parameter of drawTaxiRoutes

If you don’t know, the setter method returned by useState can take two types of arguments: the type of the variable, and a callback returning the new value.
This callback takes one parameter, the current value of the variable.

So instead of passing routes as a parameter of your method, you can do something like this :

setRoutes((oldValue) => {...oldValue, [N+1]: result})

That way, the value of oldValue will always be the last updated value.

Hope it helps 🙂

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading