i’m building a webapp using React and Google maps. I want to calculate distance between 2 places using driving. I’m getting an error when updating state, i’m not sure what’s wrong.
Uncaught TypeError: Cannot read properties of undefined (reading ‘0’)
I’ve indicated the error line in the code.
I know that setState
is asynchronous and useEffect
normally helps with this.
I tried placing that setState
in its own useEffect
but that still gave an error.
import React, { useState, useRef, useEffect } from "react";
import {
useJsApiLoader,
Autocomplete,
} from "@react-google-maps/api";
const center = { lat: 48.8584, lng: 2.2945 };
export default function Test() {
const [map, setMap] = useState(/** @type google.maps.Map */ (null));
const [directionsResponse, setDirectionsResponse] = useState(null);
const [distanceText, setDistanceText] = useState();
const [durationText, setDurationText] = useState();
const [distanceCalc, setDistanceCalc] = useState();
const [durationCalc, setDurationCalc] = useState();
const [result, setResult] = useState();
const { isLoaded } = useJsApiLoader({
id: "google-map-script",
googleMapsApiKey: process.env.REACT_APP_GOOGLEMAPS_KEY,
libraries: ["maps", "places"],
});
/** @type React.MutableRefObject<HTMLInputElement> */
const originRef = useRef();
/** @type React.MutableRefObject<HTMLInputElement> */
const destinationRef = useRef();
const calculateRoute = async () => {
console.log("Clicked");
if (originRef.current.value === "" || destinationRef.current.value === "") {
return;
}
// eslint-disable-next-line no-undef
const directionsService = new google.maps.DirectionsService();
const mapResult = await directionsService.route({
origin: originRef.current.value,
destination: destinationRef.current.value,
// eslint-disable-next-line no-undef
travelMode: google.maps.TravelMode.DRIVING,
});
setResult(mapResult);
console.log("Result2: ", result);
};
useEffect(() => {
console.log("I'm being triggered");
if (result) {
setDistanceText(result.routes[0].legs[0].distance.text); //error line
setDurationText(result.routes[0].leg[0].duration.text); //error line
setDistanceCalc(result.routes[0].leg[0].distance.value); //error line
setDurationCalc(result.routes[0].leg[0].duration.value); //error line
}
}, [result]);
useEffect(() => {
console.log("Distance Text: ", distanceText);
console.log("Duration Text: ", durationText);
console.log("Distance Calc: ", distanceCalc);
console.log("Distance Calc: ", durationCalc);
}, [distanceText, durationText, durationCalc, distanceCalc]);
return (
<>
<Autocomplete>
<input type="text" placeholder="Origin" ref={originRef} />
</Autocomplete>
<Autocomplete>
<input type="text" placeholder="Destination" ref={destinationRef} />
</Autocomplete>
<button onClick={() => calculateRoute()}>Calculate</button>
</>
);
}
Any assistance would be appreciated.
2
Answers
There are typos in your code where you are using leg instead of legs. Update your useEffect code with above code.
Try this in your code :