Arturo RV
Arturo RV

Reputation: 63

google maps callback on ES6 file

I am trying to add the callback on an ES6 file but it does not find it.

I get this error message: "initMap is not a function"

my files are this way:

<div id="map"></div>
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=<myKey>&callback=initMap"></script>

and my js file is:

export function initMap()
{
    map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: -34.397, lng: 150.644},
        zoom: 8
    });

    fetch('/data/markers.json')
      .then(function(response){return response.json()})
      .then(plotMarkers);
}

I am using browserify and babelify to transpile the js file

I have tried to move things up and down and no luck so far, the only way it works is adding the initMap function directly on the html as this guide reads:

https://developers.google.com/maps/documentation/javascript/adding-a-google-map

Actually I could not find/understand where the functions on ES6 are running (which the scope is) I printed the this value inside the initMap function and it is undefined.

Upvotes: 5

Views: 3507

Answers (2)

Fabian von Ellerts
Fabian von Ellerts

Reputation: 5201

If you want to deliver your ES6 code without transpiling (using <script type="module"> which is always defered), you might run into the same problem and the solution above will not always work.

I think the problem is that the execution order of defered scripts is a little random and if the API script runs before your ES6 code, the error will still show.

You can fix this by removing &callback=initMap from the API <script> and waiting for the API to be defined instead:

const googleDefined = (callback) => typeof google !== 'undefined' ? callback() : setTimeout(() => googleDefined(callback), 100)

googleDefined(() => {
    // init map
})
...

Upvotes: 0

Ionică Bizău
Ionică Bizău

Reputation: 113365

By using callback=initMap, Google Maps expects that initMap will be a global.

You can expose it as a global by doing window.initMap = initMap:

window.initMap = () => {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: -34.397, lng: 150.644},
        zoom: 8
    });

    fetch('/data/markers.json')
      .then(function(response){return response.json()})
      .then(plotMarkers);
};

The other way is to import the script and expose the global in the other file, like you mentioned:

import * as mapObj from "./modules/map";
window.initMap = mapObj.initMap

Upvotes: 9

Related Questions