39

I create a react app using the cli called create-react-app. Look like Facebook did lots of things underneath, such as webpack etc. However, I guess it may also has some limitations. I try to follow this tutorial to load google map api. And when I debug my code, I can see the google map has been successfully referenced.enter image description here.

But then I click play and let application finishes running. I got google is not defined error from webpackHotDevClient.js and my application crashes.

enter image description here

enter image description here

Since webpack compile the files on the fly, I assume it has trouble to load google map via https?

Any thoughts?

eded
  • 3,778
  • 8
  • 28
  • 42

7 Answers7

87

As mentioned in the user guide, you need to explicitly read any global variables from window. Put this at the top of the file and it will work:

const google = window.google;

The reason we enforce this is because people commonly misunderstand the difference between local variables, imported modules, and global variables, and so we want to always make it clear in the code when you use a global variable.

By the way, this is not related to Webpack or HTTPS. You see this because we use a linting rule that forbids unknown global variables.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • Good to know. Thanks for the reply – eded May 01 '17 at 15:58
  • I had the same issue in Vue.js with Nuxt.js. Your answer worked for me as well. – Samir Haddad Dec 14 '17 at 12:13
  • thanks, i face the problem when use react-geosuggest and your answer help me. – dhidy Jan 30 '18 at 09:43
  • 1
    I tried this but then I got an error saying to place imports at the top of the file. Putting this below the imports didn't work. So I had to use /* global google */ at the top. – nCardot Oct 22 '18 at 16:43
  • Hi Dan, Just now i searched your "user guide" link for [window, global, explicit] and came up empty. Did the info on this move someplace else? – Love and peace - Joe Codeswell Oct 26 '18 at 21:22
  • I had a weird issue where i could add a global script on my index page using `script src` and then calling the function (detectBrowser.js) without issue. Once it was deployed it wouldn't work unless i specified `window.detectBrowser()` There must be some difference between envs? It was deployed using npm ci, so it is possible dependencies were different. – dmo Jan 16 '19 at 17:42
  • When you need typescript: type google = typeof window.google; – Richard Lindhout Jan 14 '22 at 16:07
16

I think the google variable is already available when you import google map from script in html. This error caused by Eslint, you can try and add the below line to the top of your file to disable ESlint

/*global google*/
Ben Hare
  • 4,365
  • 5
  • 27
  • 44
voquockhanh
  • 356
  • 2
  • 6
7

I have a better solution then @Dan's you can do it like this

window.google = window.google ? window.google : {}

OR

const google = window.google = window.google ? window.google : {}

If google is available then no problem if not then empty Object will be temporarily assigned till your scripts are loaded.

In case es-lint throws undefined google error, update the globals in eslint configuration file:

{
    "globals": {
        "google": "readonly"
    }
}

OR

For a specific file use case define like below on the top of the file

/*global google*/
Black Mamba
  • 13,632
  • 6
  • 82
  • 105
5

Hi you can use withGoogleMap like so:

import { withGoogleMap, GoogleMap, Marker, InfoWindow } from "react-google-maps";

const google = window.google;

class MapComponent extends Component {
....

<GoogleMap>
.....
.....
.....
</GoogleMap>

export default withGoogleMap(MapComponent);
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
Undefined
  • 51
  • 1
  • 2
1

.eslintrc.json

{
    // ...
    "globals": {
     "google": "readonly"
    }
}
Kelvin Schoofs
  • 8,323
  • 1
  • 12
  • 31
Lucas Breitembach
  • 1,515
  • 11
  • 15
0
yarn add @types/googlemaps 

OR

npm i --save @types/googlemaps
ebed meleck
  • 313
  • 2
  • 5
  • See "[answer]" and [Explaining entirely code-based answers](https://meta.stackoverflow.com/q/392712/128421)". While this might be technically correct, it doesn't explain why it solves the problem or should be the selected answer. We should educate along with helping solve the problem. – the Tin Man Nov 28 '22 at 19:37
  • Please don't post code-only answers. The main audience, future readers, will be grateful to see explained *why* this answers the question instead of having to infer it from the code. Also, since this is an old question, please explain how it complements *all* other answers. – Gert Arnold Nov 28 '22 at 20:05
0

If you are using React, you can use it like this eg.

function RenderGoogleButton (){
    function handleCallbackResponse(response) {
        console.log("CredencialJWT:  "+response.credential)
    }

    useEffect(() => {
        const google = window.google  //check this
        google.accounts.id.initialize({
            client_id: YOUR_CLIENT_ID,
            callback: handleCallbackResponse
        })

        google.accounts.id.renderButton(
            document.getElementById("signInDiv"),
            { theme: "outline", size: "large" }
        )
        console.log("RenderGoogleButton")
    }, [])        
    return (<div id="signInDiv"></div>)
}

Note: const google = window.google or /* global google */ both are correct. On the above eg. I used the first one.

Omar
  • 21
  • 2