Project

General

Profile

loading script after google map api has been loaded?

Added by Arjan Vermeij over 12 years ago

I downloaded markerwithlabel.js from http://google-maps-utility-library-v3.googlecode.com/svn/trunk to see if I can add markers with a label to a Google Map. The examples work in my browser, chrome. The examples do something like:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&amp;sensor=false"></script>
<script type="text/javascript" src="../src/markerwithlabel.js"></script>

But in a Wt application, where/when do I load the markerwithlabel.js script? For example, if I change src/Wt/WGoogleMap.C, line 178, into (really, just as an example to show what the problem is):

const std::string gmuri = "http://www.google.com/jsapi?key=" + googlekey;
app->require(gmuri, "google");
app->require("resources/scripts/markerwithlabel.js");

then I get the following JavaScript error:

Uncaught TypeError: Cannot read property 'OverlayView' of undefined

The culprit is line 70 of markerwithlabel.js, where it says:

MarkerLabel_.prototype = new google.maps.OverlayView();

It is as if the google map api has not been loaded. I tried several other things, always with a similar result.

Perhaps I need to wait loading markerwithlabel.js until the google map api has been loaded?

The fact that I'm not fluent in JavaScript may be a compromising factor ...

Any help would be greatly appreciated. Thanks, Arjan.


Replies (5)

RE: loading script after google map api has been loaded? - Added by Bradley Looy about 8 years ago

I'm having the exact same problem.

RE: loading script after google map api has been loaded? - Added by Bradley Looy about 8 years ago

Perhaps a jQuery getScript after the google api load?

RE: loading script after google map api has been loaded? - Added by Koen Deforche about 8 years ago

Hey,

Google API itself loads libraries asynchronously. So you need to react to a load event when asking google to load a particular library: see for example how it's done further down in WGoogleMap.

If you want to load additional libraries conditionally, then you need to use a JSignal to get back to the server to do the subsequent require().

         << "google.load(\"maps\", \"" << (apiVersion_ == Version2 ? '2' : '3')
     << "\", {other_params:\"sensor=false\", callback: "
     << initFunction << "});"
     << "}";

RE: loading script after google map api has been loaded? - Added by Bradley Looy about 8 years ago

Thank you. I was able to do just as you suggested. I added a JSignal to the WGoogleMap widget and emitted as follows in the initFunction (for when the api loads):

strm << "{ " << initFunction << " = function() {"
"""var self = " << jsRef() << ";"
"""if (!self) { "
""   "setTimeout(" << initFunction << ", 0);"
""   "return;"
"} else { " << googleApiLoaded_.createCall() << " }";

Then in my app I connect to the signal and load the MarkerWithLabel javascript:

std::cout << "VcsWebPageMap::googleApiLoaded" << std::endl;

// load marker label script for map
WApplication::instance()->require("js/markerwithlabel.js");

Thanks again.

RE: loading script after google map api has been loaded? - Added by yvan vander sanden almost 8 years ago

I was struggling with the same, but I still trouble filling in the blanks with the information above. Eventually I came up with this solution. I think it might be easier this way. The main difference is the use of doGmJavaScript, which is triggered when google maps has been loaded.

// GoogleMaps.h
#pragma once
#include <Wt/WGoogleMap>
#include <Wt/WJavaScript>

class GoogleMap : public Wt::WGoogleMap
{
public:
  GoogleMap(Wt::WContainerWidget * parent);

private:
  void loadScripts();
  Wt::JSignal<void> mapsLoaded;
};

// GoogleMaps.cpp
#include "GoogleMap.h"

#include <Wt/WContainerWidget>
#include <Wt/WApplication>

GoogleMap::GoogleMap(Wt::WContainerWidget * parent) : Wt::WGoogleMap(Wt::WGoogleMap::Version3, parent), mapsLoaded(this, "mapsLoaded")
{
  setPositionScheme(Wt::PositionScheme::Absolute);
  resize("100%", "100%");

  mapsLoaded.connect(this, &GoogleMap::loadScripts);
  this->doGmJavaScript(mapsLoaded.createCall());
}

void GoogleMap::loadScripts() {
  Wt::WApplication::instance()->require("js/googleplaces.js");
}
    (1-5/5)