[angularjs] TypeError: window.initMap is not a function

I am following this tutorial, basically copy all the code

https://developers.google.com/maps/documentation/javascript/tutorial

but got an error saying that the initMap function is not a function. I am using angularjs in my project, could that be causing problems?

I copied the same code into plunker and it works just fine... What are the possible issues?

This question is related to angularjs google-maps google-maps-api-3

The answer is


In my case, I had to load the Map on my Wordpress website and the problem was that the Google's api script was loading before the initMap(). Therefore, I solved the problem with a delay:

<script>
function initMap() {
     // Your Javascript Codes for the map
     ...
}

<?php
// Delay for 5 seconds
sleep(5);
?>

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


In my case there was a formatting issue earlier on, so the error was a consequence of something else. My server was rendering the lat/lon values with commas instead of periods, because of different regional settings.


Actually the error is being generated by the initMap in the Google's api script

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

so basically when the Google Map API is loaded then the initMap function is executed. If you don't have an initMap function, then the initMap is not a function error is generated.

So basically what you have to do is one of the following options:

  1. to create an initMap function
  2. replace the callback function with one of your own that created for the same purpose but named it something else
  3. replace the &callback=angular.noop if you just want an empty function() (only if you use angular)

Put this in your html body (taken from the official angular.js website):

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>

I believe that you were using some older angular.js files since you don't have any issues in plunker and therefore you got the specified error.


In addition to @DB.Null's answer, I used Function.prototype as no-op (no-operation) function on #3 instead of angular.noop (I don't have angular in my project).

So this...

<script async defer src="https://maps.googleapis.com/maps/api/js?key=API_KEY_HERE&callback=Function.prototype" type="text/javascript"></script>


Could be your initMap function is in a $(document).ready function. If it is then it won't work, it has to be outside of any other functions.


your call back method probably is not globally accessible. in my case I'd used transpoiled ES6 codes via webpack which caused my callback method not being global anymore.

Try to attach your callback method explicitly to window like so right after your callback method declaration and see the result

window.initMap = initMap;

it worked for me.


Create initMap method between "" tag or load javascript file before call google api.

_x000D_
_x000D_
<script src="Scripts/main.js"></script>_x000D_
_x000D_
<script src="https://maps.googleapis.com/maps/api/js?key=abcde&libraries=places&callback=initMap" async defer></script>
_x000D_
_x000D_
_x000D_


My explanation of this problem:

The .....&callback=initMap" async defer></script> makes that script load async (in parallel with DOM) and after load - execute initMap function. NOTICE that initMap() in global scope! We can't declare our initMap() after google's script because it should already be at the moment of finish async load. Although we can't load our script before this, because we need google's function to execute ours. This is like vicious circle.

Three solutions:

1'st and worst: make google's script load synchronously

  1. remove async defer
  2. remove &callback=initMap in src attribute
  3. put <script tag with your code after google's script

2'nd and best: just do this =)

  1. leave .....&callback=initMap" async defer></script> as is
  2. and put google's <script tag after your script
  3. write in your script

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

    this allow you load google's script async and run yours just after that

3'rd and strange: it will work... some times =)

  1. do same but simply write in global scope

    function initMap() {
      // your code
    }
    

    and if you write it in global scope, that will work regardless of what which code loads faster, your (sync) or google's (async). More often your wins


I had a similar error. The answers here helped me figure out what to do.

index.html

 <!--The div element for the map -->
 <div id="map"></div>

<!--The link to external javascript file that has initMap() function-->
 <script src="main.js">

<!--Google api, this calls initMap() function-->
 <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYWY&callback=initMap">
</script>

main.js // This gives error


// The initMap function has not been executed
const initMap = () => {
const mapDisplayElement = document.getElementById('map');
  // The address is Uluru
const address = {lat: -25.344, lng: 131.036};
  // The zoom property specifies the zoom level for the map. Zoom: 0 is the lowest zoom,and displays the entire earth.
const map = new google.maps.Map(mapDisplayElement, { zoom: 4, center: address });
const marker = new google.maps.Marker({ position: address, map });
};

The answers here helped me figure out a solution. I used an immediately invoked the function (IIFE ) to work around it.

The error is as at the time of calling the google maps api the initMap() function has not executed.

main.js // This works

const mapDisplayElement = document.getElementById('map');
// The address is Uluru
// Run the initMap() function imidiately, 
(initMap = () => {
  const address = {lat: -25.344, lng: 131.036};
  // The zoom property specifies the zoom level for the map. Zoom: 0 is the lowest zoom,and displays the entire earth.
  const map = new google.maps.Map(mapDisplayElement, { zoom: 4, center: address });
  const marker = new google.maps.Marker({ position: address, map });
})();

Removing =initMap worked for me:

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

The problem has to do with the async attribute in the script tag. The Callback Function is trying to call "initMap()" when it doesn't really exists by the time the request finished.

To solve this I placed the Goole Maps Api Script bellow the script where my initMap function was declared.

Hope this helps


For me the main difference was the declaration of the function....

INSTEAD OF

function initMap() {
    ...
}

THIS WORKED

window.initMap = function () {
    ...
}

Solved by adding

<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=XXXXXXX&callback=initMap">
    <!--
        https://developers.google.com/maps/documentation/javascript/examples/map-geolocation
    -->
</script>

At the beginning of the same file which contains the rest of the code with function initMap(). It's definitely not the best solution, but it works..

But I think that if you would transform function initMap() to something like var=initMap() and then $(function () ... it would work too.


This may seem obvious but just in case: If someone placed the JS code inside $(document).ready like this:

     $(document).ready(function() {
       ... Google Maps JS code ...
      }

Then that's the problem because using async defer when loading the Google Maps API library, it will load asynchronously, and when it finishes loading, will look for the callback function, which needs to be available by then.

So, you just need to put the code outside $(document).ready, and:

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

at the very bottom, so your page loads FAST :-)


I have been struggling for several days with this very popular in the last few months issue - "initMap is not a function".

Those two threads helped me:

  1. How to make a callback to Google Maps init in separate files of a web app

  2. Defer attribute doesn't work with Google Maps API?

Why does the map open sometimes and sometimes not. It depends on several factors like speed of connection, environment, etc. Because the initialization function sometimes runs after the google maps API kicks in, that's why the map is not displayed and the browser console throws an error. For me removing only the async attribute fixed the issue. The defer attribute stays.

If async is present: The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing) If async is not present and defer is present: The script is executed when the page has finished parsing If neither async or defer is present: The script is fetched and executed immediately, before the browser continues parsing the page Source - http://www.w3schools.com/tags/att_script_defer.asp

Hope that helps. Cheers.


I am using React and I had mentioned &callback=initMap in the script as below

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

then is just removed the &callback=initMap part now there is no such error as window.initMap is not a function in the console.


Examples related to angularjs

AngularJs directive not updating another directive's scope ERROR in Cannot find module 'node-sass' CORS: credentials mode is 'include' CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 Print Html template in Angular 2 (ng-print in Angular 2) $http.get(...).success is not a function Angular 1.6.0: "Possibly unhandled rejection" error Find object by its property in array of objects with AngularJS way Error: Cannot invoke an expression whose type lacks a call signature

Examples related to google-maps

GoogleMaps API KEY for testing Google Maps shows "For development purposes only" java.lang.NoClassDefFoundError:failed resolution of :Lorg/apache/http/ProtocolVersion How to import JSON File into a TypeScript file? Googlemaps API Key for Localhost Getting "Cannot call a class as a function" in my React Project ERROR: Google Maps API error: MissingKeyMapError This page didn't load Google Maps correctly. See the JavaScript console for technical details Google Maps API warning: NoApiKeys ApiNotActivatedMapError for simple html page using google-places-api

Examples related to google-maps-api-3

Google Maps shows "For development purposes only" Googlemaps API Key for Localhost ERROR: Google Maps API error: MissingKeyMapError Google Maps API warning: NoApiKeys Google Maps JavaScript API RefererNotAllowedMapError This API project is not authorized to use this API. Please ensure that this API is activated in the APIs Console TypeError: window.initMap is not a function Google maps Marker Label with multiple characters Google Maps how to Show city or an Area outline How to use SVG markers in Google Maps API v3