0

I've successfully been able to render the Markers for react-google-maps, but when I started trying to use DirectionsRenderer, I ran into this 'google is not defined' issue. I scoured StackOverflow and the web in general for solutions to this, anywhere from declaring 'google' as a global to playing around with the withScriptjs syntax, and nothing has worked. I'm running out of ideas. Sidenote: I'm deliberately avoiding using the 'recompose' library from the docs because even the library's author thinks Hooks are better...so idk, maybe give me a solution that doesn't require 'recompose' if possible? Thanks a million.

Here's my code:

/* global google */
import React, { useState, useEffect } from 'react'
import { withGoogleMap, GoogleMap, Marker, DirectionsRenderer } from 'react-google-maps'
import './App.css'

function MyDirectionsRenderer(props) {
  const [directions, setDirections] = useState(null);
  const { origin, destination, travelMode } = props;

  useEffect(() => {
    const directionsService = new google.maps.DirectionsService();
    directionsService.route(
      {
        origin: new google.maps.LatLng(origin.lat, origin.lng),
        destination: new google.maps.LatLng(destination.lat, destination.lng),
        travelMode: travelMode
      },
      (result, status) => {
        if (status === google.maps.DirectionsStatus.OK) {
          setDirections(result);
        } else {
          console.error(`error fetching directions ${result}`);
        }
      }
    );
  }, [directions, destination.lat, destination.lng, origin.lat, origin.lng, travelMode]);

  return (
    <React.Fragment>
      {directions && <DirectionsRenderer directions={directions} />}
    </React.Fragment>
  );
}

class Map extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            directions: null
        }
    }

    render(){
        const MyMapComponent = withGoogleMap(props => {
            return (
            <GoogleMap
                defaultZoom={10}
                defaultCenter={{ lat: 42.681340, lng: -89.026930 }}
            >
                <Marker
                    position = {{lat: 42.681340, lng: -89.026930}}
                />
                <MyDirectionsRenderer
                  origin= {{lat: 42.681339, lng: -89.026932}}
                  destination= {{lat: 28.250200, lng: -82.714080}}
                  travelMode= {google.maps.TravelMode.DRIVING}
                />
            </GoogleMap>
            )
        })
        return (
            <MyMapComponent
                loadingElement={<div style={{ height: `100%` }} />}
                containerElement={<div style={{ height: `400px` }} />}
                mapElement={<div style={{ height: `100%` }} />}
            />
        )
    }
}

export default Map

Edit: I updated the code here to reflect the current status of the project and any existing problems with it. Currently, the problem is that I can't see the route on my map.

  • May be you missed this ` directions={props.directions}` - `{props.directions && }` – ravibagul91 Aug 12 '19 at 02:10
  • Thanks for your comment! I just tried your suggestion, and the error still comes up. I store the state variable "directions" in the DirectionsRenderer "directions" attribute, so it wouldn't refer to the props. – Steven Boutcher Aug 13 '19 at 13:20
  • I also found out that if I write "window.google..." for all the instances of "google," it gives me a new error: "Cannot read property 'maps' of undefined" – Steven Boutcher Aug 13 '19 at 13:21

1 Answers1

0

Since ESLint is not aware that the variable google is a global, you can declare a variable you referenced as a global by adding the following to the top of your file:

/* global google */

then the error 'google' is not defined should disappear.

And last but not least, the instance of google.maps.DirectionsService could be created only once the Google Maps APIs is loaded. The following example demonstrates how to accomplish it:

<GoogleMap
    defaultZoom={4}
    defaultCenter={{ lat: 27.71415, lng: -82.3583 }}
>
    <MyDirectionsRenderer
      origin={{ lat: 27.71415, lng: -82.3583 }}
      destination={{ lat: 42.681339, lng: -89.026932 }}
      travelMode={google.maps.TravelMode.DRIVING}
    />
</GoogleMap>

where

function MyDirectionsRenderer(props) {
  const [directions, setDirections] = useState(null);
  const { origin, destination, travelMode } = props;

  useEffect(() => {
    const directionsService = new google.maps.DirectionsService();
    directionsService.route(
      {
        origin: new google.maps.LatLng(origin.lat, origin.lng),
        destination: new google.maps.LatLng(destination.lat, destination.lng),
        travelMode: travelMode
      },
      (result, status) => {
        if (status === google.maps.DirectionsStatus.OK) {
          setDirections(result);
        } else {
          console.error(`error fetching directions ${result}`);
        }
      }
    );
  }, [directions]);

  return (
    <React.Fragment>
      {directions && <DirectionsRenderer directions={directions} />}
    </React.Fragment>
  );
}
Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
  • 1
    Thanks Vadim! I'm going to try this when I get home from work. I managed to get rid of the "google is not defined" error by doing what you said with the /* global google */ a few days ago, and by using a script tag in my index.html head instead of the withScriptjs() method. But what I have now is an error that tells me my API Key isn't authorized to access the DirectionsService API, even though I have it enabled on the Cloud console for my project. – Steven Boutcher Aug 15 '19 at 12:19
  • 1
    So it worked! The error is gone. Somehow I still can't see the route on the map, though. Is there a reason that might be? – Steven Boutcher Aug 17 '19 at 01:03