Ask your WordPress questions! Pay money and get answers fast! (more info)

Javascript issue - TypeError: gpx.get_name is not a function WordPress

  • SOLVED

The next version of my mapping plugin [[LINK href="http://www.mapmarker.com"]]http://www.mapmarker.com[[/LINK]] will allow users to add GPX-tracks and GPX-metadata.

A first version which used jquery .on("loaded") to load the gpx metadata already worked.
See the panel below the map here: [[LINK href="http://spbas.mapsmarker.com/?p=1"]]http://spbas.mapsmarker.com/?p=1[[/LINK]]
The unminified gpx code can be found at the end of [[LINK href="http://spbas.mapsmarker.com/wp-content/plugins/leaflet-maps-marker-pro/leaflet-dist/leaflet.js"]]http://spbas.mapsmarker.com/wp-content/plugins/leaflet-maps-marker-pro/leaflet-dist/leaflet.js[[/LINK]]

Within this map I used the following code to load the metadata:

function display_gpx_ebf1bca3() {
var gpx_panel = document.getElementById("gpx-panel-ebf1bca3");
var gpx_url = "http://spbas.mapsmarker.com/wp-content/uploads/2013/08/gpx-demo.gpx";

function _t(t) { return gpx_panel.getElementsByTagName(t)[0]; }
function _c(c) { return gpx_panel.getElementsByClassName(c)[0]; }

new L.GPX(gpx_url, {
async: true,
max_point_interval: 15000,
marker_options: { ... },
polyline_options: { ... },
}).on("loaded", function(e) {
var gpx = e.target;
console.log(gpx);
_c("gpx-name").textContent = gpx.get_name();
_c("gpx-start").textContent = gpx.get_start_time().toDateString() + ", " + gpx.get_start_time().toLocaleTimeString();
_c("gpx-distance").textContent = (gpx.get_distance()/1000).toFixed(2);
_c("gpx-duration-total").textContent = gpx.get_duration_string(gpx.get_total_time());
_c("gpx-avpace").textContent = gpx.get_duration_string(gpx.get_moving_pace(), true);
_c("gpx-elevation-gain").textContent = gpx.get_elevation_gain().toFixed(0);
_c("gpx-elevation-loss").textContent = gpx.get_elevation_loss().toFixed(0);
_c("gpx-elevation-net").textContent = gpx.get_elevation_gain().toFixed(0) - gpx.get_elevation_loss().toFixed(0);
}).addTo(lmm_map_ebf1bca3);
}
display_gpx_ebf1bca3();


As I dont want to use jquery .on("loaded") - my plugin does not รปse jquery in order to load maps faster - I changed the code in the
current development version - unfortunately now the gpx metadata in the panel below the map is not shown anymore.
See the panel below the map on this second demo map: [[LINK href="http://pro.mapsmarker.com/?p=106"]]http://pro.mapsmarker.com/?p=106[[/LINK]]
The unminified gpx code can be found at the end of [[LINK href="http://pro.mapsmarker.com/wp-content/plugins/leaflet-maps-marker-pro/leaflet-dist/leaflet.js"]]http://pro.mapsmarker.com/wp-content/plugins/leaflet-maps-marker-pro/leaflet-dist/leaflet.js[[/LINK]]

In the console I am getting the following error when calling the second map:

TypeError: gpx.get_name is not a function
_c("gpx-name").textContent = gpx.get_name();

Within the second map I tried using this code to load the metadata:

function display_gpx_3f904b2b() {
var gpx_panel = document.getElementById("gpx-panel-3f904b2b");
var gpx_url = "http://pro.mapsmarker.com/wp-content/uploads/2013/08/runtastic_20130814_0537_Rennradfahren.gpx";

function _t(t) { return gpx_panel.getElementsByTagName(t)[0]; }
function _c(c) { return gpx_panel.getElementsByClassName(c)[0]; }

new L.GPX(gpx_url, {
//info: gpx data is now preloaded by a php-proxy to overcome cross-domain limitations
gpx_content: "<?xml version="1.0" encoding="UTF-8"?> ... </gpx>\n",
async: true,
max_point_interval: 15000,
marker_options: { ... },
polyline_options: { ...},
}).addTo(lmm_map_3f904b2b);

//document.addEventListener("DOMContentLoaded", function(e) { //not working in IE8, use attachEvent instead
window.onload = function(e) {
console.log("this text should be displayed in console");
var gpx = e.target;
console.log(gpx);
_c("gpx-name").textContent = gpx.get_name();
_c("gpx-start").textContent = gpx.get_start_time().toDateString() + ", " + gpx.get_start_time().toLocaleTimeString();
_c("gpx-distance").textContent = (gpx.get_distance()/1000).toFixed(2);
_c("gpx-duration-total").textContent = gpx.get_duration_string(gpx.get_total_time());
_c("gpx-avpace").textContent = gpx.get_duration_string(gpx.get_moving_pace(), true);
if (isNaN(gpx.get_average_hr())) { _c("gpx-avghr").textContent = "n/a"; } else { _c("gpx-avghr").textContent = gpx.get_average_hr() + "bpm"; }
_c("gpx-elevation-gain").textContent = gpx.get_elevation_gain().toFixed(0);
_c("gpx-elevation-loss").textContent = gpx.get_elevation_loss().toFixed(0);
_c("gpx-elevation-net").textContent = gpx.get_elevation_gain().toFixed(0) - gpx.get_elevation_loss().toFixed(0);
//});
};
}
display_gpx_3f904b2b();


My first guess was that I should bind the .onload-function(e) to the L.GPX-object by

var gpx_track = new L.GPX(...);
gpx_track.onload = function(e) {


Unfortunately this didnt work (function was never fired) as well as many other solutions I tried.

What am I missing here? Why cant the function gpx.get_name() not be run on the second map? One reminder: any proposed solution must NOT include jquery functions!

Answers (1)

2013-08-21

Ross Wilson answers:

In your code for the window load handler you have:
var gpx = e.target;

This is likely setting gpx equal to the window object, which doesn't have the get_name() function

you can either create a global variable when you create your gpx object like

window.gpx = new L.GPX(...

and then in your event handler call window.gpx.get_name()

The other option is to take your last bit of code and bind the event listener
gpx_track.addEventListener('load', function(e) {...});


Robert Harm comments:

Hi,
solution 1 (window.gpx) works - although I `d rather like to use .addEventLister as I could fire this earlier on "DOMContentLoaded". Unfortunately I dont get the example to work - please see the example page.

I used the following code:

var gpx_track = new L.GPX(gpx_url, { ... }).addTo(lmm_map_36c5e981);
if (!gpx_track.addEventListener) {
console.log("attachEvent - IE8");
gpx_track.attachEvent("DOMContentLoaded", function(e) {
console.log("attachEvent in function (e)");
var gpx = e.target;
_c("gpx-name").textContent = window.gpx.get_name();
_c("gpx-start").textContent = window.gpx.get_start_time().toDateString() + ", " + window.gpx.get_start_time().toLocaleTimeString();

_c("gpx-distance").textContent = (window.gpx.get_distance()/1000).toFixed(2);

_c("gpx-duration-total").textContent = window.gpx.get_duration_string(window.gpx.get_total_time());
_c("gpx-avpace").textContent = window.gpx.get_duration_string(window.gpx.get_moving_pace(), true);
if (isNaN(window.gpx.get_average_hr())) { _c("gpx-avghr").textContent = "n/a"; } else { _c("gpx-avghr").textContent = window.gpx.get_average_hr() + "bpm"; }
_c("gpx-elevation-gain").textContent = window.gpx.get_elevation_gain().toFixed(0);
_c("gpx-elevation-loss").textContent = window.gpx.get_elevation_loss().toFixed(0);
_c("gpx-elevation-net").textContent = window.gpx.get_elevation_gain().toFixed(0) - window.gpx.get_elevation_loss().toFixed(0);


});
} else {
console.log("addEventListener- IE9+");
gpx_track.addEventListener("DOMContentLoaded", function(e) {
console.log("addEventListener in function (e)");
var gpx = e.target;
_c("gpx-name").textContent = window.gpx.get_name();
_c("gpx-start").textContent = window.gpx.get_start_time().toDateString() + ", " + window.gpx.get_start_time().toLocaleTimeString();

_c("gpx-distance").textContent = (window.gpx.get_distance()/1000).toFixed(2);

_c("gpx-duration-total").textContent = window.gpx.get_duration_string(window.gpx.get_total_time());
_c("gpx-avpace").textContent = window.gpx.get_duration_string(window.gpx.get_moving_pace(), true);
if (isNaN(window.gpx.get_average_hr())) { _c("gpx-avghr").textContent = "n/a"; } else { _c("gpx-avghr").textContent = window.gpx.get_average_hr() + "bpm"; }
_c("gpx-elevation-gain").textContent = window.gpx.get_elevation_gain().toFixed(0);
_c("gpx-elevation-loss").textContent = window.gpx.get_elevation_loss().toFixed(0);
_c("gpx-elevation-net").textContent = window.gpx.get_elevation_gain().toFixed(0) - window.gpx.get_elevation_loss().toFixed(0);


});
}


the console.log-text within the function(e) is never fired. Can you please tell me what I am missing here?


Ross Wilson comments:

Robert,

In looking more into the leafletJs API, the .on method is actually a function of leaflet.js, not jQuery. JQuery does have a function named the same, but .on can be safely used without jQuery. See here for the event methods that are available for leafletjs: [[LINK href="http://leafletjs.com/reference.html#events"]]http://leafletjs.com/reference.html#events[[/LINK]]

The "loaded" event that the gpx plugin is not the same as the dom/window onLoad event. If you look at line 197 here in the leaflet gpx code, you can see that it is specifically firing the "loaded" event..admittedly this is confusing and they should probably namespace or qualify their event names to make them clear, like .fire("gpx_loaded").
[[LINK href="https://github.com/mpetazzoni/leaflet-gpx/blob/master/gpx.js#L197"]]https://github.com/mpetazzoni/leaflet-gpx/blob/master/gpx.js#L197[[/LINK]]


Robert Harm comments:

Ross,

thx for the input about namespaces - forwarded it to the gpx plugin author.

Anyway I switched back to window.onload() as I couldnt get the

gpx_track.addEventListener("DOMContentLoaded", function(e) {

to work :-/
best,

Robert