Gnutyud
Gnutyud

Reputation: 11

How to destroy google map on demand rides and deliveries in React

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

Answers (0)

Related Questions