I'm using Next.js version 12.3.1 and React.js 18.2.0. When I select point A and point B the direction service and direction renderer gets called and the map prints the direction with the markers. But when I change points A and B the map prints a new direction but the very first direction/line stays on the map. How do I fix the issue? Here is the Map functions file:
import React, { useCallback, useState } from "react";
import CustomGoogleMap from "@components/core/CustomGoogleMap";
import { Box } from "@mui/material";
import { anyObjectType } from "@services/types";
import MapAPI from "@services/api/map";
import { CreateBookingActions } from "@services/constants";
import { useCreateBookingContext } from "@contexts/CreateBookingContext";
const BookingMap: React.FC<BookingMapProps> = ({
memoizedloadingPoint,
memoizedunloadingPoint,
memoizedwaypointsList,
setToast,
setLoadingPoint,
setUnLoadingPoint,
}) => {
const cbCtx = useCreateBookingContext();
const { state, dispatch } = cbCtx;
const { waypointsList } = state;
const [call, setCall] = useState(false);
const handleLoadingPointDragLocation = useCallback(
async (lat: number, lng: number) => {
if (lat && lng) {
const query = {
latlng: `${lat},${lng}`,
};
const { response, error }: any = await MapAPI.onDrag(query);
if (response) {
setLoadingPoint({
...response.data.data,
});
} else {
setToast("Somthing went wrong", "error");
}
}
},
[]
);
const handleUnLoadingPointDragLocation = useCallback(
async (lat: number, lng: number) => {
if (lat && lng) {
const query = {
latlng: `${lat},${lng}`,
};
const { response, error }: any = await MapAPI.onDrag(query);
if (response) {
setUnLoadingPoint({
...response.data.data,
});
} else {
setToast("Somthing went wrong", "error");
}
}
},
[]
);
const setWaypointsList = (val: any[]) => {
dispatch({
type: CreateBookingActions.SET_WAYPOINT_LIST,
payload: val,
});
};
const handleStopageDragLocation = useCallback(
async (lat: number, lng: number, index: number) => {
if (lat && lng) {
const query = {
latlng: `${lat},${lng}`,
};
const { response, error }: any = await MapAPI.onDrag(query);
if (response) {
const updatedWaypoints = JSON.parse(JSON.stringify(waypointsList));
updatedWaypoints.splice(index, 1, { ...response.data.data });
setWaypointsList([...updatedWaypoints]);
setCall(true);
} else {
setToast("Somthing went wrong", "error");
}
}
},
[]
);
return (
<Box sx={{ height: "420px" }}>
<CustomGoogleMap
call={call}
setCall={setCall}
loadingP={memoizedloadingPoint}
unloadingP={memoizedunloadingPoint}
waypointsList2={memoizedwaypointsList}
handleLoadingPointDragLocation={handleLoadingPointDragLocation}
handleUnLoadingPointDragLocation={handleUnLoadingPointDragLocation}
handleStopageDragLocation={handleStopageDragLocation}
/>
</Box>
);
};
export default BookingMap;
interface BookingMapProps {
memoizedloadingPoint: anyObjectType;
memoizedunloadingPoint: anyObjectType;
memoizedwaypointsList: any[];
setToast: (a: string, b: string) => void;
setLoadingPoint: (a: anyObjectType) => void;
setUnLoadingPoint: (a: anyObjectType) => void;
}
Here is the google map file:
import React, { useEffect, useState, memo } from "react";
import {
GoogleMap,
MarkerF,
DirectionsRenderer,
DirectionsService,
InfoWindow,
useLoadScript,
LoadScriptNext,
} from "@react-google-maps/api";
import LoadingMarker from "../SvgIcons/loading-marker.svg";
import UnLoadingMarker from "../SvgIcons/unloading-marker.svg";
import StoppageIcon from "../SvgIcons/stopageIcon.svg";
import { CircularProgress } from "@mui/material";
import { Box } from "@mui/system";
import { isEmptyArray } from "@services/utils";
import { anyObjectType, Dispatcher } from "@services/types";
const containerStyle = {
width: "100%",
height: "100%",
};
const center = {
lat: 23.810331,
lng: 90.412521,
};
interface CustomLatLong {
latitude: number;
longitude: number;
textEn: string;
}
type CustomDirectionsWaypoint = google.maps.DirectionsWaypoint & CustomLatLong;
interface CustomGoogleMapProps {
call: Boolean;
setCall: Dispatcher<boolean>;
handleStopageDragLocation?: (a: number, b: number, c: number) => void;
handleLoadingPointDragLocation?: (a: number, b: number) => void;
handleUnLoadingPointDragLocation?: (a: number, b: number) => void;
waypointsList2: CustomDirectionsWaypoint[];
loadingP: anyObjectType;
unloadingP: anyObjectType;
isAddressModal?: Boolean;
}
const CustomGoogleMap: React.FC<CustomGoogleMapProps> = (props) => {
const {
call,
setCall,
loadingP,
unloadingP,
waypointsList2,
handleLoadingPointDragLocation,
handleUnLoadingPointDragLocation,
handleStopageDragLocation,
isAddressModal = false,
} = props;
// const { isLoaded, loadError } = useLoadScript({
// googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY!,
// });
const [infoBox, setInfoWindow] = useState({
position: {
lat: 0,
lng: 0,
},
info: "",
});
const [directions, setDirections] = useState(null);
console.log("point:", loadingP, unloadingP);
useEffect(() => {
if (loadingP.latitude && unloadingP.latitude) {
setCall(true);
}
}, [loadingP.latitude, unloadingP.latitude]);
const directionsCallback = (response: any) => {
if (response !== null) {
console.log("directionsCallback called");
if (response.status === "OK") {
setCall(false);
setDirections(response);
}
}
};
const getDirectionRender = () => {
return (
<DirectionsService
options={{
destination: {
lat: unloadingP.latitude,
lng: unloadingP.longitude,
},
origin: {
lat: loadingP.latitude,
lng: loadingP.longitude,
},
travelMode: google.maps.TravelMode.DRIVING,
waypoints: waypointsList2.map(({ latitude, longitude }) => {
return {
location: {
lat: latitude,
lng: longitude,
}.toString(),
stopover: false,
};
}),
}}
callback={directionsCallback}
/>
);
};
// if (loadError) {
// return <div>Map cannot be loaded right now, sorry.</div>;
// }
const renderMap = () => {
return (
<LoadScriptNext
googleMapsApiKey={process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY!}
>
<GoogleMap
mapContainerStyle={containerStyle}
center={
loadingP.latitude
? {
lat: loadingP.latitude,
lng: loadingP.longitude,
}
: center
}
zoom={10}
onClick={({ latLng }) => {
isAddressModal &&
handleLoadingPointDragLocation &&
handleLoadingPointDragLocation(latLng!.lat(), latLng!.lng());
}}
>
{loadingP.latitude &&
unloadingP.latitude &&
call &&
getDirectionRender()}
{directions && (
<DirectionsRenderer
options={{
directions: directions,
suppressMarkers: true,
}}
/>
)}
{infoBox.position.lat && (
<InfoWindow
// options={infoBoxOptions}
position={infoBox.position}
onCloseClick={() =>
setInfoWindow({
position: {
lat: 0,
lng: 0,
},
info: "",
})
}
>
<p> {infoBox.info}</p>
</InfoWindow>
)}
<MarkerF
key={loadingP.latitude}
draggable
onDragEnd={({ latLng }) => {
handleLoadingPointDragLocation &&
handleLoadingPointDragLocation(latLng!.lat(), latLng!.lng());
}}
position={{ lat: loadingP.latitude, lng: loadingP.longitude }}
icon={LoadingMarker}
onClick={() =>
setInfoWindow({
...infoBox,
position: {
lat: loadingP.latitude,
lng: loadingP.longitude,
},
info: loadingP.textEn,
})
}
/>
<MarkerF
key={unloadingP.latitude}
draggable
onDragEnd={({ latLng }) => {
handleUnLoadingPointDragLocation &&
handleUnLoadingPointDragLocation(latLng!.lat(), latLng!.lng());
}}
position={{
lat: unloadingP.latitude,
lng: unloadingP.longitude,
}}
icon={UnLoadingMarker}
onClick={() =>
setInfoWindow({
...infoBox,
position: {
lat: unloadingP.latitude,
lng: unloadingP.longitude,
},
info: unloadingP.textEn,
})
}
/>
{!isEmptyArray(waypointsList2) &&
waypointsList2.map((item, index) => {
return (
<MarkerF
key={index}
draggable
visible
onDragEnd={({ latLng }) => {
handleStopageDragLocation &&
handleStopageDragLocation(
latLng!.lat(),
latLng!.lng(),
index
);
}}
position={{
lat: item.latitude,
lng: item.longitude,
}}
icon={StoppageIcon}
onClick={() =>
setInfoWindow({
...infoBox,
position: {
lat: item.latitude,
lng: item.longitude,
},
info: item.textEn,
})
}
/>
);
})}
</GoogleMap>
</LoadScriptNext>
);
};
return renderMap();
};
export default memo(CustomGoogleMap);