So I apologize if I mess the terms here up, I'm relatively new to using jQuery in Drupal. I'm trying to implement a custom Google Map application with the V3 API. When I started mocking the module up I had no problem invoking the google maps function callback without my JS being wrapped in a closure. However, needing to use jQuery functions pointed me to wrapping my JS in a closure and referencing jquery, as well as attaching my js to the Drupal.behaviors object. The problem that I have is that now it seems that the callback on my Google Maps script tag is out of scope. I'm not sure if this is due to the closure, due to how I'm loading the script, or something else that I haven't come across yet. The specific JS error I get is

Uncaught (in promise) message: "initMap is not a function" 

My module JS is

(function ($) {
Drupal.behaviors.gmap_json = {
attach : function (context, settings){
var map, alumLayer, chapterLayer, assocLayer, userLayer;
  function initMap() {
    map = new google.maps.Map(document.getElementById('json-map'), {
      zoom: 4,
      center: {lat: 38.43, lng: -90}
    icon: 'purple.png',

      alert('it works');

And my module php is

function gmap_json_block_info() {
    $blocks = array();

    $blocks['gmap_json'] = array(
      'info' => t('Google Maps with GeoJSON'),

    return $blocks;

  function gmap_json_block_view($delta = '') {
    $block = array();
    if ($delta == 'gmap_json') {
      $block['subject'] = '';
      $block['content'] = '<div id="json-map" style="width:1100px; height:500px; margin:auto;"></div>';
    $path = drupal_get_path('module', 'gmap_json');  
    drupal_add_js('https://maps.googleapis.com/maps/api/js?key=mykey&callback=initMap', 'external');
    drupal_add_js($path. '/gmap_json.js', 'file');

    return $block;

So, what am I doing wrong and how can I either bring my callback into scope? Or what's the right way to set this up.

EDIT: I have attempted to implement both the answer as well as one of the comments.

drupal_add_js('https://maps.googleapis.com/maps/api/js?key=mykey&callback=initMap', array('type' => 'external', 'defer' => 'defer'));

Adding a "defer" via array doesn't produce any changes, and changing the order of my calls to the js only changes where the error gets called.

  • Reverse the order of calls for drupal_add_js?
    – Kevin
    Feb 26, 2019 at 15:01
  • this didn't work, but it changed where I get the 'is not a function' error...
    – nizz0k
    Feb 27, 2019 at 12:05

1 Answer 1


You could/should add the defer tag to your maps drupal_add_js as recommended by google (https://developers.google.com/maps/documentation/javascript/tutorial)

You'll get abit better page performance and should get rid of your issue you're facing as the google maps code will always be loaded after your scripts

Here's how you can add the defer tag: How to drupal_add_js an external and defer script

  • unfortunately, I either implemented your advice wrong or it didn't work.
    – nizz0k
    Feb 27, 2019 at 12:15
  • I tried this, both with drupal_add_js and by adding a script tag to the block's markup. Variations of the same error, init map is not a function.
    – nizz0k
    Feb 27, 2019 at 12:22
  • so, the issue is not call order, it's scope. When I remove the closure the map's call is respected. When I wrap it, function not defined.
    – nizz0k
    Mar 4, 2019 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.