Reputation: 311
I have a function as below.
I am trying to call this with
var testVar = new genericYiiLocation();
console.log(testVar.getLongitude());
however, I this.getLongitude() always has an empty this.longitude.
I have checked that this.longitude contains the values as expected when being set in locateSuccess(loc) and it seems ok.
Any guidance would be appreciated.
function genericYiiLocation() {
console.log('genericYiiLocation: Creating location handler');
this.longitude= '';
this.latitude= '';
this.accuracy= '';
if (Modernizr.geolocation) {
console.log('genericYiiLocation: Location supported');
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(locateSuccess, locateFail);
}
else {
alert('genericYiiLocation: Geolocation is not supported in your current browser.');
return false;
}
} else {
alert ('genericYiiLocation: no native location support');
return false;
}
function locateSuccess(loc){
console.log('genericYiiLocation: storing location data');
this.longitude = loc.coords.longitude;
}
// Unsuccessful geolocation
function locateFail(geoPositionError) {
switch (geoPositionError.code) {
case 0: // UNKNOWN_ERROR
alert('An unknown error occurred, sorry');
break;
case 1: // PERMISSION_DENIED
alert('Permission to use Geolocation was denied');
break;
case 2: // POSITION_UNAVAILABLE
alert('Couldn\'t find you...');
break;
case 3: // TIMEOUT
alert('The Geolocation request took too long and timed out');
break;
default:
}
}
this.getLongitude = function(){
console.log('long: '+this.longitude);
return this.longitude;
}
}
Upvotes: 1
Views: 176
Reputation: 735
As far as I understand the reason is:
The this
inside your callback locateSuccess
is different from the this
outside the callback. To achieve what you are intending to, you can bind the callbacks localSuccess
& locateFail
to this
using Function.prototype.bind
.
Upvotes: 1
Reputation: 2557
The following line:
navigator.geolocation.getCurrentPosition(locateSuccess, locateFail);
causes your locateSuccess
function to be executed in the global scope of your page. Hence, when the locateSuccess
function tries to access this
, it references the window
object instead of your genericYiiLocation
object.
A quick way to fix this would be to bind the genericYiiLocation
object to another variable in its scope, then reference it within the locateSuccess
closure like so:
function genericYiiLocation() {
console.log('genericYiiLocation: Creating location handler');
this.longitude= '';
this.latitude= '';
this.accuracy= '';
// ADDED
var me = this;
if (Modernizr.geolocation) {
console.log('genericYiiLocation: Location supported');
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(locateSuccess, locateFail);
}
else {
alert('genericYiiLocation: Geolocation is not supported in your current browser.');
return false;
}
} else {
alert ('genericYiiLocation: no native location support');
return false;
}
function locateSuccess(loc){
console.log('genericYiiLocation: storing location data');
// CHANGED
me.longitude = loc.coords.longitude;
}
// Unsuccessful geolocation
function locateFail(geoPositionError) {
switch (geoPositionError.code) {
case 0: // UNKNOWN_ERROR
alert('An unknown error occurred, sorry');
break;
case 1: // PERMISSION_DENIED
alert('Permission to use Geolocation was denied');
break;
case 2: // POSITION_UNAVAILABLE
alert('Couldn\'t find you...');
break;
case 3: // TIMEOUT
alert('The Geolocation request took too long and timed out');
break;
default:
}
}
this.getLongitude = function(){
console.log('long: '+this.longitude);
return this.longitude;
}
}
Upvotes: 0