Bablu Ahmed
Bablu Ahmed

Reputation: 5010

React Google Maps API (ReferenceError: google is not defined)

I'm using react-google-maps/api node module. I need to set the value of zoomControlOptions is TOP_LEFT but I ended up getting this error Uncaught ReferenceError: google is not defined. Here is the link to the repo.

I'm getting the error here

const options = {
  zoomControl: true,
  mapTypeControl: false,
  minZoom: 2,
  streetViewControl: false,
  zoomControlOptions: {
    position: google.maps.ControlPosition.TOP_LEFT, // google is undefined here
  },
};

Please help me :)

Upvotes: 3

Views: 17073

Answers (5)

Hammad Ali
Hammad Ali

Reputation: 51

This happens because you are rendering the Google Map before it's loaded.

Instead of using LoadScript, use useJsApiLoader.

import {
  GoogleMap,
  MarkerF,
  useJsApiLoader,
} from "@react-google-maps/api";


function RenderMap() {
  const { isLoaded } = useJsApiLoader({ googleMapsApiKey });
  if (!isLoaded) {
    return null;
  }
  // google is guaranteed to be defined now
  return <GoogleMap>...</GoogleMap>
}

useJsApiLoader has the following type signature:

declare function useJsApiLoader({ id, version, nonce, googleMapsApiKey, language, region, libraries, preventGoogleFontsLoading, mapIds, authReferrerPolicy, }: UseLoadScriptOptions): {
    isLoaded: boolean;
    loadError: Error | undefined;
};

Upvotes: 5

nonybrighto
nonybrighto

Reputation: 9581

You can try doing this. Especially with next.js

zoomControlOptions: {
   position:
     typeof google !== "undefined"
     ? google.maps.ControlPosition.TOP_RIGHT
     : null,
}

Upvotes: 0

Arthur Ribeiro
Arthur Ribeiro

Reputation: 79

Loading maps and markers in React with googleapi

import React from 'react'

const loadScript = (src) =>
new Promise((resolve, reject) => {
  if (document.querySelector(`script[src="${src}"`)) return resolve()
  const script = document.createElement('script')
  script.src = src
  script.onload = () => resolve()
  script.onerror = (err) => reject(err)
  document.body.appendChild(script)
})

const MyMapComponent = ({center, zoom, marker}) => {
  const ref = React.useRef();
  const src=`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_KEY}&callback=initMap`
  
  loadScript(src)
    .then(() => {
      /*global google*/
      // console.log("Load script google: ", google)
    })
    .catch(console.error)
    React.useEffect(() => {
      const map = new window.google.maps.Map(ref.current, {
        center,
        zoom,
      });
        new google.maps.Marker({
          position: {  
             lat: -15.770,
             lng: -44.233
          },
          map,
          icon: "https://yourlovedIcon.png",            })
      ))
    });

  return <div ref={ref} id="map" style={{height: '100vh', width: '50vh'}}/>;
}

function Maps() {
 
  const center = { 
    lat: -15.770,
    lng: -44.233 };
  const zoom = 10
   
  return (
          <MyMapComponent 
          center={center}
          zoom={zoom}
          marker={center}
          />
)
}

export default Maps

If you want to use an customized API to get cordinates from internet:

import React from 'react'
import axios from 'axios';

const loadScript = (src) =>
new Promise((resolve, reject) => {
  if (document.querySelector(`script[src="${src}"`)) return resolve()
  const script = document.createElement('script')
  script.src = src
  script.onload = () => resolve()
  script.onerror = (err) => reject(err)
  document.body.appendChild(script)
})

const MyMapComponent = ({center, zoom, marker}) => {
  const ref = React.useRef();
  const src=`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_KEY}&callback=initMap`
  
  loadScript(src)
    .then(() => {
      /*global google*/
      // console.log("Load script google: ", google)
    })
    .catch(console.error)
    React.useEffect(() => {
      const map = new window.google.maps.Map(ref.current, {
        center,
        zoom,
      });
      marker.features.map(selectedData => (
        new google.maps.Marker({
          position: {  
            lat: selectedData.coordinates[0],
            lng: selectedData.coordinates[1]
          },
          map,
          icon: "https://yourlovedIcon.png",
        })
      ))
    });

  return <div ref={ref} id="map" style={{height: '100vh', width: '50vh'}}/>;
}

function Maps() {
  const [data, setData] = React.useState('');

  React.useEffect(() => {
    async function fetchData() {
      const response = await axios.get("https:\\YOURAPI.LOAD")
      setData(response.data)
    }
    fetchData();
  },[])
  
  const center = { 
    lat: -15.770,
    lng: -44.233 };
  const zoom = 10
    
  return data && 
          <MyMapComponent 
          center={center}
          zoom={zoom}
          marker={data}
          />
}

export default Maps

Upvotes: 0

Rodder
Rodder

Reputation: 359

Try to define "options" inside your component and add "window", like

position: window.google.maps.ControlPosition.TOP_LEFT

Also, you can put just a number

BOTTOM: 11
BOTTOM_CENTER: 11
BOTTOM_LEFT: 10
BOTTOM_RIGHT: 12
CENTER: 13
LEFT: 5
LEFT_BOTTOM: 6
LEFT_CENTER: 4
LEFT_TOP: 5
RIGHT: 7
RIGHT_BOTTOM: 9
RIGHT_CENTER: 8
RIGHT_TOP: 7
TOP: 2
TOP_CENTER: 2
TOP_LEFT: 1
TOP_RIGHT: 3

Upvotes: 0

AhmCho
AhmCho

Reputation: 390

Try defining google variable explicitly like this:

const google = window.google;

Also, you may read out this answer as well

Upvotes: 3

Related Questions