45

I am struggling to load gmaps api with requireJS . This is what I've tried:

requirejs.config({
    urlArgs: "noCache=" + (new Date).getTime(),
    paths : {
        "jquery": "vendor/jquery-1.8.2.min",
        "bootstrap": "vendor/bootstrap.min",      
        "underscore": "libs/underscore-min",
        "backbone": "libs/backbone-min",    
        "template": "libs/template",
        "gmaps": "http://maps.google.com/maps/api/js?v=3&sensor=false"
    },
    shim: {
        'backbone': {
            deps: ['jquery', 'underscore'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'bootstrap': {
            deps: ['jquery']
        },
        'gmaps': {
            deps: ['jquery']
        },
        'main':{
            deps: ['jquery','gmaps']   
        }
    }
});

require(["main"], function (main) {})

But inside main.js when I try to instantiate the geocoder i got ,,undefined is not a function" error.

var geocoder = new google.maps.Geocoder();

Any ideas what could I be doing wrong?

hjuster
  • 3,604
  • 8
  • 30
  • 48

7 Answers7

64

I've managed to sort it out with the async plugin.

A quick example is:

require.config({
    paths: {
        'async': 'lib/requirejs-plugins/src/async'
    }
});

define(['async!http://maps.google.com/maps/api/js?sensor=false'], function() {
    // Google Maps API and all its dependencies will be loaded here.
});
Rubens Mariuzzo
  • 25,735
  • 25
  • 111
  • 145
hjuster
  • 3,604
  • 8
  • 30
  • 48
12

Thanks to user1706254 cause official documentation : https://github.com/millermedeiros/requirejs-plugins/ was using the keyword 'define' that wasn't working for me but 'require' is working fine.

I couldn't load directly :

require(["goog!maps,3,other_params:sensor=false"], function(){});

But using the asynchronous way did the trick :

require(['async!http://maps.google.com/maps/api/js?sensor=false'], function(){});
hugsbrugs
  • 3,073
  • 2
  • 24
  • 33
  • Hm, it is working for me. The goog module requires that 'async' and 'propertyParser' are defined in the paths, exactly like that, including camel casing. BTW, sensor does nothing now and can be left out – light24bulbs Nov 02 '14 at 18:54
  • Can anyone get the API key to work with this? As far as I can tell, this doesn't support including an API key in the URL. It isn't hard to just hardcode one into the plugin, but I think that is missing the point. I now prefer to just use the async module to request the url manually, since that gives you full control – light24bulbs Nov 04 '14 at 18:56
5

You don't need the async plugin to use Google Maps with require.js. The goal can be achieved using only a simple shim config:

require.config({
    paths: {
        gmaps: '//maps.googleapis.com/maps/api/js?' // question mark is appended to prevent require.js from adding a .js suffix
    },
    shim: {
        gmaps: {
            exports: 'google.maps'
        }
    }
});

require(['gmaps'], function (gmaps) {
    var center = {lat: -34.397, lng: 150.644}; 
    var map = new gmaps.Map(document.getElementById('map'), {
        center: center,
        zoom: 8
    });
    new gmaps.Marker({
        map: map,
        position: center
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script>

<div id="map" style="width: 100%; height: 200px"></div>
Finesse
  • 6,684
  • 6
  • 44
  • 60
4

Following on from hjuster here's a quick example of how to use the async plugin

https://gist.github.com/millermedeiros/882682

codekipple
  • 241
  • 2
  • 8
4

There is also goog plugin (requires async and propertyParser), available on github

Usage example for google maps:

require(["goog!maps,3,other_params:sensor=false"], function(){});
loleksy
  • 201
  • 4
  • 4
  • This is the way to do it. For me it worked with google places with no problems: ```goog!maps,3,other_params:key=XXX&libraries=places``` – sucotronic Oct 13 '15 at 12:08
0

@hjuster's answer led me the way and I've solved by a callback function.

define(['async!http://maps.google.com/maps/api/js?key=YOURKEY!callback'],
    function (_ExpectedMap) {
                              callback(); 
                           });

Notice the !callback at the end of the url starts with async!, callback method is being called when load operation is done.

function callback()
{
    //Now load google maps API dependant libraries
    require(['gmapsLib'], function (googlemaps) {
                     window.GMaps = googlemaps;
                   }
}

There is another question I lately noticed, another function (onLoad) is in use instead of callback to prevent from timeout error. Interesting.

Community
  • 1
  • 1
Davut Gürbüz
  • 4,462
  • 4
  • 38
  • 73
-3

Couldn't make the plugins work for some reason, but this workaround saved my day:

 require(['https://apis.google.com/js/client.js?onload=doNothing'], function() {
    // Poll until gapi is ready
    function checkGAPI() {
      if (gapi && gapi.client) {
        self.init();
      } else {
        setTimeout(checkGAPI, 100);
      }
    }

    checkGAPI();
  });
});

Just check if gapi is ready every 100 millisec, until it finally loads.

Found the code in this article http://dailyjs.com/2012/12/06/backbone-tutorial-2/

I guess you can also try it with

if (google && google.maps && google.maps.Geocoder) {
    // now google.maps.Geocoder is gonna be defined for sure :)
}
DarthVanger
  • 658
  • 7
  • 10