1

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

Gnutyud
  • 11
  • 1
  • Have you tried setting the map to `null` every unmount? – Yrll Feb 16 '23 at 02:58
  • Yes, Do you have any idea? – Gnutyud Feb 17 '23 at 03:35
  • I hope you can provide a sandbox or snippet that reproduces the issue so that we can take a look into it, but I'm not sure if the ODRD can be reproduced in such? Any kind of scenario without using the ODRD but somehow reproduces the issue would be nice to have. Since reading all your posted code seems hard to really see what's causing the issue. – Yrll Feb 17 '23 at 06:12

0 Answers0