• Resolved Troglos

    (@troglos)


    Ciao Nicola,

    I am using AFC to embed google maps, but with SCK installed I got the Uncaught ReferenceError: google is not defined error.
    Just to be sure I’ve deactivated Autoptimize, but the error is still there.

    The page I need help with: [log in to see the link]

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Author Nicola Modugno

    (@shark986)

    Hello @troglos,
    the problem is that you init the map even if the Google Maps script is not loaded.

    Setting up maps on document.ready is the common way (as I saw on themes and builders), but it is not the right way.
    The maps should be inited through a callback passed to the Maps script. Give a look on the first snippet code on the following link for a reference: do you see the “callback” parameter on the Maps script?
    https://developers.google.com/maps/documentation/javascript/tutorial.

    ACF provides a filter to customize the Map behaviour (https://www.advancedcustomfields.com/resources/google-map/#google-map%20api) so you could:

    1) Use that filter in the functions.php of the child theme to add the callback parameter to the Maps script.

    add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');
    function my_acf_google_map_api( $api ){
      $api['callback'] = 'initMaps';
      return $api;  
    }

    2) Change the init method of the map in your JavaScript code, from this

    $(document).ready(function(){
      $('.acf-map').each(function(){
        // create map
        map = new_map( $(this) );
      });
    });

    to this:

    function initMaps() {
      $('.acf-map').each(function(){
        // create map
        map = new_map( $(this) );
      });
    }

    In this way the map init will depend on the Maps script (regardless of WHEN the Maps script is loaded)!

    Please, let me know ??
    Nicola

    PS: I added a bit of theory and link references to this answer because this thread could help other peoples.

    PS: I have not tested the code, be careful with it.

    Thread Starter Troglos

    (@troglos)

    Ciao Nicola,

    Thanks for the answer, but I’ve not being able to make it work.

    I’ve added the filter in functions.php and modified the jQuery function as you suggested. No console error now, but no map either.

    Plugin Author Nicola Modugno

    (@shark986)

    @troglos, my fault!

    I have read better the ACF documentation and it seems that the filter I have mentioned above customize only the backend map! In fact they later explain what needs to be on the template page (including the Google Maps script!) to get things work.

    Do you confirm to me that you manually added the Google Map script in the frontend?

    If yes:

    1) No need about the “callback” item in the array in the filter function (you have to do a step backwards on this point – I think that it should remain the filter to customize the API key);

    2) Change the JavaScript code with this (I have rewrited it):

    // ACF Google Map
    // https://www.advancedcustomfields.com/resources/google-map/
      
    // global var
    var map = null;
    
    function initMaps() {
      (function($) {
        function new_map( $el ) { 
          // var
          var $markers = $el.find('.marker');
          // vars
          var args = {
            zoom    : 16,
            center    : new google.maps.LatLng(0, 0),
            mapTypeId : google.maps.MapTypeId.ROADMAP
          };  
          // create map           
          var map = new google.maps.Map( $el[0], args); 
          // add a markers reference
          map.markers = []; 
          // add markers
          $markers.each(function(){   
              add_marker( $(this), map );   
          }); 
          // center map
          center_map( map );  
          // return
          return map;
        }
        function add_marker( $marker, map ) {
          // var
          var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
          // marker
          var image = '/wp-content/uploads/marker.png';
          // create marker
          var marker = new google.maps.Marker({
            position  : latlng,
            map     : map,
            icon: image
          });
          // add to array
          map.markers.push( marker );
          // if marker contains HTML, add it to an infoWindow
          if( $marker.html() )
          {
            // create info window
            var infowindow = new google.maps.InfoWindow({
              content   : $marker.html()
            });
            // show info window when marker is clicked
            google.maps.event.addListener(marker, 'click', function() {
              infowindow.open( map, marker );
            });
          }
        }
        function center_map( map ) {
          // vars
          var bounds = new google.maps.LatLngBounds();
          // loop through all markers and create bounds
          $.each( map.markers, function( i, marker ){
            var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
            bounds.extend( latlng );
          });
          // only 1 marker?
          if( map.markers.length == 1 )
          {
            // set center of map
              map.setCenter( bounds.getCenter() );
              map.setZoom( 16 );
          }
          else
          {
            // fit to bounds
            map.fitBounds( bounds );
          }
        }
        $('.acf-map').each(function(){
          // create map
          map = new_map( $(this) );
        });
      })(jQuery);
    }

    3) Modify the Google Map script inclusion, adding the key/value pair for the callback parameter: the source should be
    https://maps.googleapis.com/maps/api/js?key=[your_key]&callback=initMaps

    Nicola

    Thread Starter Troglos

    (@troglos)

    Now I get
    “Ob?{message: “initMaps is not a function”, name: “InvalidValueError”, …”

    I’ve added the callback this way:
    wp_enqueue_script( 'maps.googleapis.com', 'https://maps.googleapis.com/maps/api/js?key=AIzaSyD6B_5U-B260qjKls1E1Oe1qGdQAVBxYj0&callback=initMaps', array( ), '', true );

    In the template file all I have is

    <?php if( have_rows('mappa_locations') ): ?>
        <div class="acf-map">
    	<?php while ( have_rows('mappa_locations') ) : the_row(); 			
    	$location = get_sub_field('location');
    	?>
    	  <div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
    	  <?php /* popup infowindow */ ?>
    	  <strong><?php the_sub_field('titolo_location'); ?></strong>
    	  <div><?php the_sub_field('indirizzo_location'); ?></div>
    	</div>
    	<?php endwhile; ?>
        </div>
    <?php endif; ?>
    • This reply was modified 6 years, 3 months ago by Troglos.
    Plugin Author Nicola Modugno

    (@shark986)

    @troglos Have you tried to remove the “async” from the app.js ?

    Thread Starter Troglos

    (@troglos)

    Yes I just tried, anyway “async” was not used for maps.googleapis.com

    Plugin Author Nicola Modugno

    (@shark986)

    @troglos if you can provide some access to the site I could make some tests (only ftp if you disable cache for the tests).

    The callback way is correct, I have reproduced your code on a custom theme and I get the map correctly loaded.

    wp_register_script( 'fe_map_script1' , get_stylesheet_directory_uri() . '/res/test.js#async', array( 'jquery' ) , '', true  );
    wp_register_script( 'fe_map_script', 'https://maps.googleapis.com/maps/api/js?key=___&callback=initMaps', array(), '', true  );
    <script type='text/javascript' async="async" src='https://localhost:8888/Wordpress/wp-content/themes/___/res/test.js?ver=4.9.8'></script>
    <script type='text/javascript' src='https://localhost:8888/Wordpress/wp-content/plugins/smart-cookie-kit/res/empty.js' data-blocked="https://maps.googleapis.com/maps/api/js?key=___&callback=initMaps&ver=4.9.8" data-sck_type="2" data-sck_unlock="profiling" data-sck_ref="Google Maps" data-sck_index="1" class="BlockedBySmartCookieKit"></script>

    I think that somewhat in the app.js is causing the problem. What I noticed is that functions positioned AFTER the commented original block of code were not loaded: in the console all of them resulted undefined.

    Thread Starter Troglos

    (@troglos)

    I’ve sent the ftp credentials via email ??

    Let me know if you need further info

    Plugin Author Nicola Modugno

    (@shark986)

    @troglos the problem was that the JS code I rewrited was nested inside another
    jQuery(function ($).
    I moved that code at the bottom of the app.js file and now the map appears!

    Check it out ??

    Thread Starter Troglos

    (@troglos)

    Great!

    Thanks a lot Nicola!

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Uncaught ReferenceError: google is not defined’ is closed to new replies.