2

This time, i'll go right to the point:

HTML:

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="code.js"></script>
</head>

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

</html>

Code.js:

$(document).ready(function () {
    var map;

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

Result:

Uncaught TypeError: window.initMap is not a function.

Tips?

Also, wonder if this part:

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

Can be moved to the same code.js file.

Gabriel
  • 5,453
  • 14
  • 63
  • 92

2 Answers2

11

Update: Dear friends, this was an awful answer. A really really awful answer.
Well, the solution was fine, the explanation not. This is my strike-through of shame :)

You don't need to set a $(document).ready() because this tells to the browser to call initMap(); when the document is ready but you have async and defer in your goolemaps script which means that when you try to execute your initiation you are missing some things.

Updated Answer: You need just the initMap() function in your javascript file. If you wrap your function inside a $(document).ready() function (closures, closures, closures people), then this function(initMap) isn't available outside the $(document).ready().

e.g: This doesn't work and returns error 'Uncaught ReferenceError: myfunc is not defined'

     $(document).ready(function(){
        myfunc = function(){
          console.log('myfunc');
        }
     })
     myfunc();

This will work:

    $(document).ready(function(){
        myfunc = function(){
            console.log('myfunc');
        }
        myfunc();
    })

and this will work:

    myfunc = function(){
        console.log('myfunc');
    }
    $(document).ready(function(){
        myfunc();
    })

Why you say? Because of how javascript scope and closures work of course :)

codegaze
  • 755
  • 7
  • 15
0
  1. leave .....&callback=initMap" async defer></script> as it is
  2. put google's <script tag as higher as possible
  3. write in your script

    function initMap() {}; // now it IS a function, lol, and it is in global
    
    $(() => { // jquery on load
      initMap = function() {
        // your code like...
        var map = new google.maps.Map(document.getElementById('map'), {...});
        // and other stuff...
      }
    })
    

my complex answer is here

Community
  • 1
  • 1
Andrey Kudriavtsev
  • 1,124
  • 11
  • 19