Search code examples
reactjsgoogle-mapsgoogle-directions-apitravel-time

react and google Directions API without map


I need the results from .route() in my internal app, not going into any map. I need the duration and distance between the origin and destination for further calculations in my app.

So far I tried it with a callback func:

function getTravelTime(origin, destination, cb) {
    const directionsService = new google.maps.DirectionsService();
    directionsService.route(
        {
            origin: origin,
            destination: destination,
            travelMode: "DRIVING"
        },
        (result, status) => {
            if (status === google.maps.DirectionsStatus.OK) {
                cb(null, {
                    duration: moment.utc(moment.duration(result.routes[0].legs[0].duration.value, 'seconds').as('milliseconds')).format('HH:mm'),
                    distance: result.routes[0].legs[0].distance.value
                });
            } else {
                cb('error');
                console.log(result);
            }
        }
    );
};

and I tried to read it like this:

let tInfo = getTravelTime(origin, destination, function (err, dist) {
   if (!err) {
      let distanceBetweenLocations = dist.distance;
      let durationBetweenLocations = dist.duration;
      // Or with saving to a state
      setTravelInformation(prevState => ({
         distance: dist.distance,
         duration: dist.duration
      }));
    }
});  

Is there any possibility to calculate distance and travel time without needing to render the map?

So far I got this, heavily shortened as I got much more logic for other components in the same file:

import {
withGoogleMap,
GoogleMap,
withScriptjs,
Marker,
DirectionsRenderer
} from "react-google-maps";

const getTravelTime = (origin, destination) => {
    const directionsService = new google.maps.DirectionsService();
    directionsService.route(
      {
        origin: origin,
        destination: destination,
        travelMode: google.maps.TravelMode.DRIVING
      },
      (result, status) => {
        console.log(result)
        if (status === google.maps.DirectionsStatus.OK) {
          setDirections(result);
        } else {
          setError(result);
        }
      }
    );
}  

Do I need to use HoC withScriptjs and wrap my component around this?


Solution

  • You could use useState and useEffect, see https://reactjs.org/docs/hooks-effect.html

    const [distance, setDistance] = useState(0);
    const [duration, setDuration] = useState(0);
    
    useEffect(() => {
      if (distance && duration) {
        console.log("Distance & Duration have updated", distance, duration);
      }
    }, [distance, duration]);
    

    When you receive Directions results, update the distance and duration with whatever value you need:

    directionsService.route({
        origin: origin,
        destination: destination,
        travelMode: google.maps.TravelMode.DRIVING
      },
      (result, status) => {
        if (status === google.maps.DirectionsStatus.OK) {
          setDistance(result.routes[0].legs[0].distance.value);
          setDuration(result.routes[0].legs[0].duration.value);
        } else {
          console.error("error fetching directions", result, status);
        }
      }
    );
    

    Here is a working snippet using @react-google-maps/api

    https://codesandbox.io/s/react-google-mapsapi-directions-service-m7qif

    You need to use a valid API key in case it doesn't work.