1

I have a code snippet that's working for my "maps" feature - following is the code:

var latlang = new google.maps.LatLng(myjsonobject[pos].geocode.latitude, myjsonobject[pos].geocode.longitude);

$('#map_canvas').gmap({
    'center': latlang, 
    'zoom': 10, 
    'disableDefaultUI':false, 
    'callback': function() {
        var self = this;                         
        self
            .addMarker({'position': this.get('map').getCenter() })
            .click(function() {
                self.openInfoWindow({ 'content': address }, this);
            });                         
    }
});

The variable latlang is provided with the latitude and longitude of a given location. Then, the map_canvas is the div where the Google map is displayed with the latlang as its inputs. In the callback function, self is a variable assigned with this. This is the place where I am confused. What is this in this context? Can anyone throw some light on getCenter() and the this inside self.openInfoWindow please?

How is the whole code working and showing me the result?

gion_13
  • 41,171
  • 10
  • 96
  • 108
Lohith Korupolu
  • 1,066
  • 1
  • 18
  • 52
  • See: http://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object-literal/13441628#13441628. Specifically this is in the context of an onclick handler so check out rule 4. But jQuery can change what `this` is as well so check out jQuery documentation. – slebetman Oct 23 '13 at 07:11
  • thanks for your response... The code is being used in my HTML5 mobile app where a set of addresses are shown as result and when I click on an address, the map is shown for that address. All this is working only for first time (first address click).i.e. if I select a new address next, the map is still showing the old address and its position :( – Lohith Korupolu Oct 23 '13 at 07:18

4 Answers4

2

'this' is context to $('#map_canvas')

The whole DOM tree of map_canvas is stored into 'this' variable

Vicky Gonsalves
  • 11,593
  • 2
  • 37
  • 58
  • thanks for your response... All this is working fine only for the first time. The code is being used in my HTML5 mobile app where a set of addresses are shown as result and when I click on an address, the map is shown for that address. All this is working only for first time (first address click).i.e. if I select a new address next, the map is still showing the old address and its position :( – Lohith Korupolu Oct 23 '13 at 07:10
1
$('#map_canvas').gmap({'center': latlang, 'zoom': 10, 'disableDefaultUI':false, 
'callback': function(   event   ) {
           var self = this;     
...

as you capture the event in that function this will (always?!) be equivalent to

$(event.currentTarget)[0]
Alex Tape
  • 2,291
  • 4
  • 26
  • 36
1

Javascript has function scope.
This actually means that inside each function this refers to a different thing.
If you want to access a certain scope in another function, a common approach is to store the desired context (this) in another variable (such as self because it's naming is suggestive of it's value).
Here's a simple demo that might clear this:

function a() {
    this.someValue = 'some value';
    var self = this;

    function b() {
        alert(this.someValue); // it's undefined, because "this" 
                               // refers to function b's context

        alert(self.someValue); // this works as expected, because self 
                               // is a reference to a's context
    }

    // call b(), to actually test this
    b();
} 
a();

To simplify your code and make it more readable, let's separate the functions and name them. So your old code:

$('#map_canvas').gmap({
    'center': latlang, 
    'zoom': 10, 
    'disableDefaultUI':false, 
    'callback': function() {
        var self = this;                         
        self
            .addMarker({'position': this.get('map').getCenter() })
            .click(function() {
                self.openInfoWindow({ 'content': address }, this);
            });                         
    }
});

becomes:

$('#map_canvas').gmap({
    'center': latlang, 
    'zoom': 10, 
    'disableDefaultUI':false, 
    'callback': callback
});

function callback() {
    var self = this;  

    this
        .addMarker({'position': this.get('map').getCenter() })
        .click(onClick);    
}

function onClick() {
    // self is callback's context
    // which actually points to the map instance

    // this points to the context of the click function, 
    // which actually is the dom element that was clicked on, 
    // which is the marker
    self.openInfoWindow({ 'content': address }, this);
}
gion_13
  • 41,171
  • 10
  • 96
  • 108
  • thanks for your response... The code is being used in my HTML5 mobile app where a set of addresses are shown as result and when I click on an address, the map is shown for that address. All this is working only for first time (first address click).i.e. if I select a new address next, the map is still showing the old address and its position :( – Lohith Korupolu Oct 23 '13 at 07:24
  • in my code, when I alert "self" it says [object, object]. The "latlang" is being updated fine (with any new address' lat, lang coordinates) but that's not reflecting in the "addmarker"... It always shows my first address! :( – Lohith Korupolu Oct 23 '13 at 07:27
  • Please see the full (updated) answer. Maybe it will help you understand the issue better :) – gion_13 Oct 23 '13 at 07:48
  • Sure. this should really help. I was going through a similar post here - http://stackoverflow.com/questions/7701077/add-marker-function-with-google-maps-api – Lohith Korupolu Oct 23 '13 at 07:57
0

'this' is a jQuery object when you are inside your own jQuery functions.

Luke Rixson
  • 607
  • 5
  • 20