Christophvh
Christophvh

Reputation: 13254

Google maps v3 API only loading after refresh / Authentication goes very slow

Using Google maps v3 API. When i visit the page with the map i sometimes get following error : "custom.js:46 Uncaught ReferenceError: google is not defined".

API's enabled on the key:

When i reload the page, everything is working fine. This doesn't work 100% of the time. Multiple reloads are needed on some occasions.

I did notice that when the map isn't loading correctly this script is running in my head tags:

<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps/api/js/AuthenticationService.Authenticate?1shttp%3A%2F%2Fmayan-co.com%2Fen%2Foutlets&amp;MYKEY&amp;callback=_xdc_._h7cv8d&amp;token=60166"></script>

After 10-20 seconds this script goes away and when i refresh the page after this script goes away, my map is working correctly.

Things i tried without results:

Loading the api script in the Head of my page:

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

My script to render the map and place markers on the map (loaded in the footer)

jQuery(document).ready(function($) {
    $('#animation').addClass('animate');

    $('.heart img').popover({
        placement: 'top',
        html: true,
        container: '#animation',
        content: function () {
            return $(this).attr('alt');
        }
    });

    $('body').on('click', function(e) {
        $('.heart img').each(function() {
            if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.heart img').has(e.target).length === 0) {
                $(this).popover('hide');
            } else {
                $(this).popover('toggle');
            }
        });
    });

    function render_map($el) {

        var $markers = $(document).find('#locations .data-source li');

        var args = {
            zoom: 16,
            center: new google.maps.LatLng(0, 0),
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            scrollwheel: false,
            mapTypeControlOptions: {
                mapTypeIds: [google.maps.MapTypeId.ROADMAP]
            }
        };

        var map = new google.maps.Map($el[0], args);

        map.markers = [];

        index = 0;
        $markers.each(function() {
            add_marker($(this), map, index);
            index++;
        });

        center_map(map);
    }

    function add_marker($marker, map, index) {
        var latlng = new google.maps.LatLng($marker.attr('data-lat'), $marker.attr('data-lng'));
        var image = '../../img/maps-leaf.png';
        var marker = new google.maps.Marker({
            position: latlng,
            map: map,
            icon: image
        });
        map.markers.push(marker);
        if ($marker.html()) {
            $('#locations .data-display').append('<li class="linkage" id="p'+index+'">'+$marker.html()+'</li>');

            $(document).on('click', '#p' + index, function() {
                infowindow.open(map, marker);
                setTimeout(function() { infowindow.close(); }, 5000);
            });

            var infowindow = new google.maps.InfoWindow({
                content: $marker.html(),
            });

            google.maps.event.addListener(marker, 'click', function() {
                infowindow.open( map, marker );
            });
        }
    }

    function center_map(map) {
        var bounds = new google.maps.LatLngBounds();
        $.each( map.markers, function( i, marker ){
            var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
            bounds.extend( latlng );
        });

        if( map.markers.length == 1 ) {
            map.setCenter( bounds.getCenter() );
            map.setZoom( 16 );
        } else {
            map.fitBounds( bounds );
        }
    }

    $(document).ready(function(){
        $('#map').each(function(){
            render_map( $(this) );
        });
    });
});

Upvotes: 3

Views: 4668

Answers (1)

martin
martin

Reputation: 96969

What you describe looks like you try to instantiate the map before the Google Maps API JavaScript is loaded (you're using async attribute there). That's why it sometimes throws google is not defined error.

In other words, document.ready is called before https://maps.googleapis.com/maps/api/js?key=MYKEY is loaded.

Google Maps API allows you to use callback parameter in the URL with a name of a function that's called after the API is fully loaded. See https://developers.google.com/maps/documentation/javascript/tutorial.

So in your case you'll use URL like:

https://maps.googleapis.com/maps/api/js?key=MYKEY&callback=initMap

And then initialize the map:

initMap() {
    var map = new google.maps.Map($el[0], args);
}

Upvotes: 6

Related Questions