Reputation: 1039
I am trying to add Google Maps to a ReactJs web app, but without any success.
I know there are some react components that wrap google maps, but they don't suit my actual needs so I have to build one myself. My problem is that I don't know how to handle the script tag required by google maps to work : <script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD6maRCH9aI1K0sWA_FRdjIQv9AJgP7aQ0&callback=initMap"
async defer></script>
I put it in index.html at first, but I get this error when I start my app in the chrome devtools :
Uncaught (in promise)
Hc {message: "initMap is not a function", name: "InvalidValueError", stack: "Error↵ at new Hc (https://maps.googleapis.com/m…I1K0sWA_FRdjIQv9AJgP7aQ0&callback=initMap:124:108"}
I've tried using fetch()
to get the script, see what it actually is, but it ask for a CORS header and thinking I don't know the exact params that this request expects I think this is not the solution.
Upvotes: 0
Views: 1692
Reputation: 1595
As @Naismith said the error is as a result of the callback=initMap
within your google maps script include.
So for it to work, you would have to implement the initMap
function like so:
<div id="map"></div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
async defer></script>
Except you're trying to display the maps within a component, in that case you can try this approach where you create a promise for the Google Maps API, and resolve that promise in a (global) callback function the Google Maps API can run. In your component code you'd then wait for the promise to be resolved before proceeding.
class Map extends React.Component {
getGoogleMaps() {
if (!this.googleMapsPromise) {
this.googleMapsPromise = new Promise((resolve) => {
// Add a global handler for when the API finishes loading
window.resolveGoogleMapsPromise = () => {
// Resolve the promise
resolve(google);
// Tidy up
delete window.resolveGoogleMapsPromise;
};
// Load the Google Maps API
const script = document.createElement("script");
const API = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
script.src = `https://maps.googleapis.com/maps/api/js?key=${API}&callback=resolveGoogleMapsPromise`;
script.async = true;
document.body.appendChild(script);
});
}
// Return a promise for the Google Maps API
return this.googleMapsPromise;
}
componentWillMount() {
// Start Google Maps API loading since we know we'll soon need it
this.getGoogleMaps();
}
componentDidMount() {
// Once the Google Maps API has finished loading, initialize the map
this.getGoogleMaps().then((google) => {
const uluru = {lat: -25.366, lng: 131.044};
const map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: laos
});
const marker = new google.maps.Marker({
position: laos,
map: map
});
});
}
render() {
return (
<div>
<div id="map" style={{width: 600, height: 300}}></div>
</div>
)
}
}
ReactDOM.render(
<Map/>,
document.getElementById('react')
);
Upvotes: 1
Reputation: 266
The reason you're getting initMap is not a function, is because apart of the script's src that you provided at the end is 'callback=initMap'. This will run a function called initMap after the script has finished loading.
If you looked at the documentation on Google's website they have an example function that you would have to put in above your script tag for google maps.
https://developers.google.com/maps/documentation/javascript/tutorial
Upvotes: 0