js-samples
js-samples copied to clipboard
Cannot find namespace 'google'.
Operating system
macOS 12.04
Browser Version
Firefox 100.0.2
How severe is the bug?
moderate
Bug description
This bug is about the code excerpt from https://developers.google.com/maps/documentation/javascript/react-map#add-map
Using the given code block (see below), will lead to
Cannot find namespace 'google'.
and Property 'google' does not exist on type 'Window & typeof globalThis'
. The imports linked in this repository does also not solve the problem.
const ref = React.useRef<HTMLDivElement>(null);
const [map, setMap] = React.useState<google.maps.Map>();
React.useEffect(() => {
if (ref.current && !map) {
setMap(new window.google.maps.Map(ref.current, {}));
}
}, [ref, map]);
Steps to reproduce
Follow the steps on https://developers.google.com/maps/documentation/javascript/react-map#typescript
Console log output
Uncaught TypeError: window.google is undefined
Source code as suggested by the guide
import React from 'react';
import { Wrapper, Status } from '@googlemaps/react-wrapper';
export const Map: React.FC<{}> = () => {
const ref = React.useRef<HTMLDivElement>(null);
const [map, setMap] = React.useState<google.maps.Map>();
React.useEffect(() => {
if (ref.current && !map) {
setMap(new window.google.maps.Map(ref.current, {}));
}
}, [ref, map]);
return <div ref={ref} />;
};
export const MyMap: React.FC = () => {
return (
<>
<Map />
</>
);
};
Edit: I thought this was the answer, but apparently it's not:
It looks like the solution is to wrap the Map
component with the Wrapper
:
export const MyMap: React.FC = () => {
return (
<>
<Wrapper apiKey={"YOUR PERSONAL API KEY"}>
<Map />
</Wrapper>
</>
);
};
Suggestion for the documentation:
Problem:
The docs mention the following code a little out of context:
const render = (status: Status) => {
return <h1>{status}</h1>;
};
<Wrapper apiKey={"YOUR_API_KEY"} render={render}>
<YourComponent/>
</Wrapper>
Especially confusing is <YourComponent/>
(as the guide creates the Map
component later)
Suggestion:
Replace YourComponent
with Map
const render = (status: Status) => {
return <h1>{status}</h1>;
};
<Wrapper apiKey={"YOUR_API_KEY"} render={render}>
<Map/>
</Wrapper>
I found a solution. The docs are rather confusing in various points. The code below is a working example, in case anyone is struggling similarly.
Would be nice, if the docs could feature a more simpler and working example like the one below :)
/**
* Packages to install:
* yarn add @googlemaps/react-wrapper
**/
import React from 'react';
import { Wrapper, Status } from '@googlemaps/react-wrapper';
/**
* Internal component you use as a pure wrapper for google maps
**/
const GoogleMap: React.FC = () => {
const myRef = React.useRef<HTMLDivElement>(null);
const [map, setMap] = React.useState<any>();
// Why `as any`? `window.google` will be set dynamically within `<Wrapper>`.
// However, typescript does not know about that. So we make it shut up.
const google = (window as any).google;
const centerPoint = { lat: 52.5167, lng: 13.3833 };
React.useEffect(() => {
if (myRef.current && !map) {
setMap(
new google.maps.Map(myRef.current, {
center: centerPoint,
zoom: 13, // IMPORTANT: Without `zoom` your map stays blank
})
);
}
}, [myRef, map]);
// IMPORTANT: You cannot move the Wrapper inside this component (for an unknown reason).
// Doing so will lead to a blank screen.
return <div ref={myRef} style={{ width: '100%', height: '500px' }} />;
};
/**
* Component you will use in the rest of your code
**/
export const MyMap: React.FC = () => {
// IMPORTANT: Wrapper must be here, cannot be above
return (
<Wrapper apiKey={'[Your API key]'}>
<GoogleMap />
</Wrapper>
);
};
Thanks for this, now I have a working example I can start playing around.
@DarkTrick Thank you for sharing your solution! We'll look at improving the code sample.