Reputation: 4783
Map class:
function Map() {
this.map;
this.userLatitude = 0;
this.userLongitude = 0;
this.startPositionReporting();
}
Map.prototype.getUserPosition = function () {
alert(this.userLatitude);
return {
latitude: this.userLatitude,
longitude: this.userLongitude
};
};
Map.prototype.startPositionReporting = function () {
var geolocationOptions = {
enableHighAccuracy : true
};
function showError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
alert("User denied the request for Geolocation.");
break;
case error.POSITION_UNAVAILABLE:
alert("Location information is unavailable.");
break;
case error.TIMEOUT:
alert("The request to get user location timed out.");
break;
case error.UNKNOWN_ERROR:
alert("An unknown error occurred.");
break;
}
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
this.userLatitude = position.coords.latitude;
this.userLongitude = position.coords.longitude;
}, null, geolocationOptions);
}
};
Calling the object:
var mapObject = new Map();
console.log(mapObject.getUserPosition()); // Why does this return 0???
I can't figure out why mapObject.getUserPosition()
is returning 0. I have checked this.userLatitude
and this.userLongitude
inside the startPositionReporting
method and they work fine. This must be something to do with scope... any ideas?
Upvotes: 0
Views: 71
Reputation: 26706
Several. The problem is that this
doesn't behave the way you think it does.
this
is bound to a function's scope, and is resolved dynamically (at the time the function is called).
Your problem is that you've got a callback fed to navigator.geolocation.getCurrentPosition
, where, in that function, you're setting properties on this
, expecting this
to be your instance.
It's not.
this
is most-likely window
, in your case.
Two solutions are:
Map.prototype.startPositionReporting = function () {
var map = this; // instance of Map
/* ... */
navigator.geolocation.getCurrentPosition(function (position) {
map.userLatitude = position.coords.latitude;
// ...
});
or
var updateMapCoords = function (position) {
this.userLatitude = position.coords.latitude;
// ...
};
Map.prototype.startPositionReporting = function () {
var map = this; // instance of Map
var updateMap = updateMapCoords.bind(map);
// returns a copy of the function with `this` set to the value passed to `bind`
// ...
navigator.geolocation.getCurrentPosition(updateMap);
// ...
Upvotes: 2
Reputation: 18566
Your problem is simple
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
this.userLatitude = position.coords.latitude;
this.userLongitude = position.coords.longitude;
}, null, geolocationOptions);
}
In this part of the startPositionReporting
-method you assume that inside your anonymous function the this
variable still references your Map object. Well, it doesn't. You need to explicitly store the scope you want to use in a variable and then use it within the anonymous function closure, like this:
var self = this;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
self.userLatitude = position.coords.latitude;
self.userLongitude = position.coords.longitude;
}, null, geolocationOptions);
}
Hope this helps!
Upvotes: 0
Reputation: 3254
Yes it is the scope problem.
var that = this;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
that.userLatitude = position.coords.latitude;
that.userLongitude = position.coords.longitude;
}, null, geolocationOptions);
}
The function that you pass in getCurrentPosition will be invoked in a different context. That is why you need to save off the reference to the context where that function was invoked.
Upvotes: 2
Reputation: 2244
navigator.geolocation.getCurrentPosition
is an asynchronous function. You need to wait until it returns before those fields will be anything other than 0.
Upvotes: 0