Question

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?

Was it helpful?

Solution

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.
});

OTHER TIPS

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(){});

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>

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

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

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(){});

@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.

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 :)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top