Hope that title makes sense.
This is part of an object I have:
The event listener attaches to the correct marker passed in the parameter but inside the function, this
points to something else.
function UserGoogleMap($mapElement) {
this.$mapElement = $mapElement;
this.map = {};
this.marker = null;
this.coords = new google.maps.LatLng(25.2697, 55.3095)
this.initMap = function () {
google.maps.event.addListener(this.marker, 'dragend', function() {
console.log(this.marker); // Undefined
pos = this.marker.getPosition();
$('#google-map-info').html("Latitude:" + pos.lat() + " Longitude: " + pos.lng());
});
}
This works with a local variable:
var marker = this.marker;
google.maps.event.addListener(marker, 'dragend', function() {
pos = marker.getPosition();
$('#google-map-info').html("Latitude:" + pos.lat() + " Longitude: " + pos.lng());
});
this.initMap();
}
Is there anyway to rewrite this to use this.marker?
or am I stuck with creating a local variable to refer to it? Also is there a way to have this.initMap()
execute automatically instead of having to add this.initMap();
at the end of the class?
Any other feedback would be appreciated.
2 Answers 2
There's nothing too elegant to be done here, just use
var that = this;
And inside your functions, use that
.
As in:
function UserGoogleMap($mapElement) {
this.$mapElement = $mapElement;
this.map = {};
this.marker = null;
this.coords = new google.maps.LatLng(25.2697, 55.3095)
var that = this;
this.initMap = function () {
google.maps.event.addListener(that.marker, 'dragend', function() {
console.log(that.marker); // not Undefined anymore! ;-)
pos = that.marker.getPosition();
$('#google-map-info').html("Latitude:" + pos.lat() + " Longitude: " + pos.lng());
});
}
}
As for the this.initMap();
part, AFAIK since JavaScript's class concept are not really classes but functions, you'll have to manually call it or really make a construct that'll call it like this:
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript#The_Constructor
The "that" solution works well, but you can also bind your function to this :
function UserGoogleMap($mapElement) {
this.$mapElement = $mapElement;
this.map = {};
this.marker = null;
this.coords = new google.maps.LatLng(25.2697, 55.3095)
this.initMap = function () {
google.maps.event.addListener(this.marker, 'dragend', function() {
console.log(this.marker);
pos = this.marker.getPosition();
$('#google-map-info').html("Latitude:" + pos.lat() + " Longitude: " + pos.lng());
}.bind(this));
}
}
There is a way to execute initMap directly :
this.initMap = function () {
google.maps.event.addListener(this.marker, 'dragend', function() {
pos = this.marker.getPosition();
$('#google-map-info').html("Latitude:" + pos.lat() + " Longitude: " + pos.lng());
}.bind(this));
return arguments.callee;
}();
But arguments.callee is deprecated (due to performance issues), so calling initMap manually is better.