1
\$\begingroup\$

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.

asked May 2, 2012 at 12:34
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

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

answered May 2, 2012 at 12:43
\$\endgroup\$
2
  • \$\begingroup\$ Just realized this after submitting the question. \$\endgroup\$ Commented May 2, 2012 at 12:48
  • \$\begingroup\$ Hehe happens all the time, np :-) \$\endgroup\$ Commented May 2, 2012 at 12:49
3
\$\begingroup\$

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.

answered Apr 15, 2014 at 10:33
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.