Reputation: 11
I was following the documentation to implement google map on demand rides and deliveries solution (ODRD) here. And my Map component in React:
const MapComponent = ({ styles }) => {
const ref = useRef(null);
const tripId = useRef<string>('');
const locationProvider =
useRef<google.maps.journeySharing.FleetEngineTripLocationProvider>();
const [error, setError] = useState<string | undefined>();
const mapOptions = useRef<MapOptionsModel>({
showAnticipatedRoutePolyline: true,
showTakenRoutePolyline: true,
destinationMarker: ICON_OPTIONS.USE_DEFAULT,
vehicleMarker: ICON_OPTIONS.USE_DEFAULT,
});
const [trip, setTrip] = useState<TripModel>({
status: null,
dropOff: null,
waypoints: null,
});
const setTripId = (newTripId: string) => {
tripId.current = newTripId;
if (locationProvider.current) locationProvider.current.tripId = newTripId;
};
const setMapOptions = (newMapOptions: MapOptionsModel) => {
mapOptions.current.showAnticipatedRoutePolyline =
newMapOptions.showAnticipatedRoutePolyline;
mapOptions.current.showTakenRoutePolyline =
newMapOptions.showTakenRoutePolyline;
mapOptions.current.destinationMarker = newMapOptions.destinationMarker;
mapOptions.current.vehicleMarker = newMapOptions.vehicleMarker;
setTripId(tripId.current);
};
const authTokenFetcher = async () => {
const response = await fetch(
`${PROVIDER_URL}/token/consumer/${tripId.current}`
);
const responseJson = await response.json();
return {
token: responseJson.jwt,
expiresInSeconds: 3300,
};
};
useEffect(() => {
locationProvider.current =
new google.maps.journeySharing.FleetEngineTripLocationProvider({
projectId: PROVIDER_PROJECT_ID,
authTokenFetcher,
tripId: tripId.current,
pollingIntervalMillis: DEFAULT_POLLING_INTERVAL_MS,
});
locationProvider.current.addListener(
'error',
(e: google.maps.ErrorEvent) => {
setError(e.error.message);
}
);
locationProvider.current.addListener(
'update',
(
e: google.maps.journeySharing.FleetEngineTripLocationProviderUpdateEvent
) => {
if (e.trip) {
setTrip({
status: e.trip.status,
dropOff: e.trip.dropOffTime,
waypoints: e.trip.remainingWaypoints,
});
setError(undefined);
}
}
);
const mapViewOptions: google.maps.journeySharing.JourneySharingMapViewOptions =
{
element: ref.current as unknown as Element,
locationProvider: locationProvider.current,
anticipatedRoutePolylineSetup: ({ defaultPolylineOptions }) => {
return {
polylineOptions: defaultPolylineOptions,
visible: mapOptions.current.showAnticipatedRoutePolyline,
};
},
takenRoutePolylineSetup: ({ defaultPolylineOptions }) => {
return {
polylineOptions: defaultPolylineOptions,
visible: mapOptions.current.showTakenRoutePolyline,
};
},
destinationMarkerSetup: ({ defaultMarkerOptions }) => {
if (
mapOptions.current.destinationMarker !== ICON_OPTIONS.USE_DEFAULT
) {
defaultMarkerOptions.icon =
mapOptions.current.destinationMarker.icon;
}
return { markerOptions: defaultMarkerOptions };
},
vehicleMarkerSetup: ({ defaultMarkerOptions }) => {
if (mapOptions.current.vehicleMarker !== ICON_OPTIONS.USE_DEFAULT) {
// Preserve some default icon properties.
if (defaultMarkerOptions.icon) {
defaultMarkerOptions.icon = Object.assign(
defaultMarkerOptions.icon,
mapOptions.current.vehicleMarker.icon
);
}
}
return { markerOptions: defaultMarkerOptions };
},
};
const mapView = new google.maps.journeySharing.JourneySharingMapView(
mapViewOptions
);
// Provide default zoom & center so the map loads even if trip ID is bad or stale.
mapView.map.setOptions(DEFAULT_MAP_OPTIONS);
}, []);
return (
<div style={styles.map} ref={ref} />
);
};
And my App component like this:
import React from 'react';
import { Wrapper, Status } from '@googlemaps/react-wrapper';
import MapComponent from './src/components/MapComponent';
import { API_KEY } from './src/utils/consts';
const render = (status: Status) => <Text>{status}</Text>;
const App = () => {
return (
<Wrapper
apiKey={API_KEY}
render={render}
version={'beta'}
// @ts-ignore
libraries={['journeySharing']}
>
<MapComponent />
</Wrapper>
);
};
Everything will works fine but I do not know how to destroy the map when component unmount in React. That's why my App always call API update the trip info.
I was tried to use clean up function in useEffect:
useEffect(() => {
locationProvider.current =
new google.maps.journeySharing.FleetEngineTripLocationProvider({
projectId: PROVIDER_PROJECT_ID,
authTokenFetcher,
tripId: tripId.current,
pollingIntervalMillis: DEFAULT_POLLING_INTERVAL_MS,
});
locationProvider.current.addListener(
'error',
(e: google.maps.ErrorEvent) => {
setError(e.error.message);
}
);
const updateEvent = locationProvider.current.addListener(
'update',
(
e: google.maps.journeySharing.FleetEngineTripLocationProviderUpdateEvent
) => {
if (e.trip) {
setTrip({
status: e.trip.status,
dropOff: e.trip.dropOffTime,
waypoints: e.trip.remainingWaypoints,
});
setError(undefined);
}
}
);
const mapViewOptions: google.maps.journeySharing.JourneySharingMapViewOptions =
{
element: ref.current as unknown as Element,
locationProvider: locationProvider.current,
anticipatedRoutePolylineSetup: ({ defaultPolylineOptions }) => {
return {
polylineOptions: defaultPolylineOptions,
visible: mapOptions.current.showAnticipatedRoutePolyline,
};
},
takenRoutePolylineSetup: ({ defaultPolylineOptions }) => {
return {
polylineOptions: defaultPolylineOptions,
visible: mapOptions.current.showTakenRoutePolyline,
};
},
destinationMarkerSetup: ({ defaultMarkerOptions }) => {
if (
mapOptions.current.destinationMarker !== ICON_OPTIONS.USE_DEFAULT
) {
defaultMarkerOptions.icon =
mapOptions.current.destinationMarker.icon;
}
return { markerOptions: defaultMarkerOptions };
},
vehicleMarkerSetup: ({ defaultMarkerOptions }) => {
if (mapOptions.current.vehicleMarker !== ICON_OPTIONS.USE_DEFAULT) {
// Preserve some default icon properties.
if (defaultMarkerOptions.icon) {
defaultMarkerOptions.icon = Object.assign(
defaultMarkerOptions.icon,
mapOptions.current.vehicleMarker.icon
);
}
}
return { markerOptions: defaultMarkerOptions };
},
};
const mapView = new google.maps.journeySharing.JourneySharingMapView(
mapViewOptions
);
// Provide default zoom & center so the map loads even if trip ID is bad or stale.
mapView.map.setOptions(DEFAULT_MAP_OPTIONS);
return () => {
mapView.map = null // or mapView.map.setmap(null);
google.maps.event.removeListener(updateEvent);
};
}, []);
But it was not working. Hope anyone can help me find out this. Thanks
Upvotes: 1
Views: 261