Skip to content
Advertisement

Google Maps can’t read property ‘extend’ of undefined after page load

I’m trying to increase page speed by loading my Google Maps two seconds after page load. While doing so, I keep on getting “Cannot read property ‘extend’ of undefined”. I know there is some asynchronous loading going on but I’m not sure how to get it in proper order to get this map to load 2 seconds after the page is done. Any help is greatly appreciated.

Page Code:

<div id="mapCont"></div>
<script defer type='text/javascript' src='/js/maps.js'></script>

maps.js

$(window).bind("load", function() { 
    $.getScript('https://maps.googleapis.com/maps/api/js?key=key', function()
{

    setTimeout(function(){ 
        function doMap(callback) {
            $("#mapCont").html('<div id="mapInfoManual" class="searchMap mb5"></div>');
        callback();
        }
        
        doMap(function() {

        initialize();
          
         var map = null;
         var markers = [];
         var openedInfoWindow ="";
         var bounds = new google.maps.LatLngBounds();
   
         function initialize() {
   
             var mapOptions = {
   
              zoom: 8,
               center: new google.maps.LatLng(64.85599578876611, -147.83363628361917),
               mapTypeId: google.maps.MapTypeId.ROADMAP,
               mapTypeControl: true,
               mapTypeControlOptions: {
                 style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
               },
               zoomControl: true,
               zoomControlOptions: {
                   style: google.maps.ZoomControlStyle.SMALL
               }
             };
             map = new google.maps.Map(document.getElementById("mapInfoManual"),
                 mapOptions);
   
   
             google.maps.event.addListener(map, 'zoom_changed', function() {
                 zoomChangeBoundsListener = google.maps.event.addListener(map, 'bounds_changed', function(event) {
                     if (this.getZoom() > 20) // Change max/min zoom here
                         this.setZoom(18);
   
                     google.maps.event.removeListener(zoomChangeBoundsListener);
                 });
         });
             addMarker();
           }
   
   
         function addMarker() {
   
               var bounds = new google.maps.LatLngBounds();
               for (i = 0; i < markersArray.length; i++) {
                 CodeAddress(markersArray[i]);
               }
             }
   
             // Address To Marker
             function CodeAddress(markerEntry) {
             var mytitle = (markersArray[i]['title']);
                     var myaddress = (markersArray[i]['address']);
                     var linkid = (markersArray[i]['linkid']);
                     var linkurl = (markersArray[i]['linkurl']);
                   var image = { url: '/images/MapPin.png', };
             var lat = markerEntry['lat'];
             var long = markerEntry['long'];
             // var myLatLng = {lat: markerEntry['lat'], lng: markerEntry['long']};
             var myLatlng = new google.maps.LatLng(parseFloat(lat),parseFloat(long));
   
                     var marker = new google.maps.Marker({
                       position: myLatlng,
                       map: map,
                       icon: image
                     });
                     bounds.extend(marker.getPosition());
                     var infoWindowContent = "<div class='cityMapInfoPop'><span style='font-weight:700;'>"+ mytitle +"</span><br /><br />" + myaddress + "<br /><br /><a href='/center/" + linkurl + "/'>More Details</a></div>";
                     openInfoWindow(marker, infoWindowContent);
                     markers.push(marker);
                     map.fitBounds(bounds);
               }
               //Info Window
   
             function openInfoWindow(marker, infoWindowContent) {
               var infowindow = new google.maps.InfoWindow({
                 content: '<div class="cityMapInfoPop">' + infoWindowContent + '</div>'
               });
   
               google.maps.event.addListener(marker, 'click', function() {
   
                 if (openedInfoWindow != "") {
                   openedInfoWindow.close();
                 }
   
                 infowindow.open(map, marker);
                 openedInfoWindow = infowindow;
               });
             }
   
    });
    }, 2000);
});

});

Advertisement

Answer

The initial https://maps.googleapis.com/maps/api/js?key=key loads additional scripts that are not being captured by your implementation. The package, https://www.npmjs.com/package/@googlemaps/js-api-loader, enables the following pattern and is probably what you want:

import { Loader } from '@googlemaps/js-api-loader';

const loader = new Loader({
  apiKey: "",
  version: "weekly",
  libraries: ["places"]
});

loader
  .load()
  .then(() => {
    doMap();
    initialize();
  })
  .catch(e => {
    // do something
  });

Alternative(use callback) if you want JQuery and your existing pattern:

window.callback = () => {
  doMap();
  initialize();
};

$(window).bind("load", function() { 
    $.getScript('https://maps.googleapis.com/maps/api/js?key=key&callback=callback', () => {}); // do nothing here

Also related: https://developers.google.com/maps/documentation/javascript/examples/programmatic-load-button

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement