0

This code from Google Maps documentation page is quite a mystery to me. The functions in the snippet refer to an object google and everything is working great.

I expected then that the object google exists at a global scope, since it is being used by global functions, who otherwise have no way of knowing about it (i.e. they are not declaring it, and it is not being passed in as a parameter)

For example if I see code like

function () {
     // do some calc
     anotherFunction(resultOfCalc)
     ...
}

I would assume that anotherFunction is available in at least the parent scope - if not the global one.

Here is the JSFiddle for the Google code. Notice I added a line console.log("Google obj:", google);

in the console it is printing

VM573:66 Uncaught ReferenceError: google is not defined
    at VM573:66

But why? The next lines in the code are

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: -33.9, lng: 151.2}
  });

  setMarkers(map);
}

and there is no compaint about the use of google.

Please help me understand this peculiar behaviour.

3
  • Here is the JSFiddle... Where is the JSFiddle? Commented Jul 16, 2017 at 4:26
  • Is there some asynchronous stuff going on there? Maybe this "google" object get loaded asynchronously and you are using it before it get loaded? Commented Jul 16, 2017 at 4:30
  • @ibrahimmahrir added it a moment after posting - initially forgot. Sorry Commented Jul 16, 2017 at 4:34

3 Answers 3

2

The library script is loaded using the JSONP technique of calling a callback when google is ready:

<script async defer src="https://maps.googleapis.com/maps/api/js?key=…&callback=initMap">
</script>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick response!
1

This issue is the script is being loaded with async defer

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

And you are calling console.log before the script loads:

console.log("Google obj:", google);("Google obj:", google);

Once the script loads the google is set as a global variable.

Your function does not have the problem because the query string callback=initMap in the script src attribute tells Google to call your function when it loads which means that the google object has been set as a global variable by this point.

In fact, the first time you run your fiddle you will get the error. But on subsequent runs you do not get the error because the script is cached by the browser and has a chance to load before your console.log is called.

Comments

0

async

Set this Boolean attribute to indicate that the browser should, if possible, execute the script asynchronously. This attribute must not be used if the src attribute is absent (i.e. for inline scripts), in this case, it would have no effect.

Dynamically inserted scripts execute asynchronously by default, so to turn on synchronous execution (i.e. scripts execute in the order they were loaded) set async=false

defer

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded. This attribute must not be used if the src attribute is absent (i.e. for inline scripts), in this case it would have no effect. To achieve a similar effect for dynamically inserted scripts use async=false instead.

as you can see in script tag you have defer and async it makes this script to be executed asynchronously with the rest of the page while the page is parsing and when you execute console.log(google) and it's undefined it means that this script loading is not finished yet. the callback parameter generate js that call this function after google file loaded.for example when your script is

<script async defer src="https://maps.googleapis.com/maps/api/js?key=…&callback=myCustomFunction">
</script>

after that file is loaded it call myCustomFucntion function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.