admin管理员组

文章数量:1415145

I'm working on a basic JavaScript weather application. I'd like to pull the geolocation from the browser and make it accessible to my other functions.

function Weather( options ) {

    this.apiKey = options.key;
    this.endpoint = options.endpoint;
    this.coordinates = {};
}

Weather.prototype.GetLocation = function( callback ) {
    if (navigator.geolocation)
    {
        navigator.geolocation.getCurrentPosition( function(position) {
            this.coordinates.latitude = position.coords.latitude;
            this.coordinates.longitude = position.coords.longitude;
        });
    }
};

Weather.prototype.GetCurrentConditions = function() {

    this.GetLocation();

    var url = this.endpoint + "weather?lat=" + this.coordinates.latitude + "&lon=" + this.coordinates.longitude;

    return this.getJSONP( url );
};

Weather.prototype.GetExtendedForecast = function() {

    this.GetLocation();

    var url = this.endpoint + "forecast/daily?lat=" + this.coordinates.latitude + "&lon=" + this.coordinates.longitude + "&cnt=7";

    return this.getJSONP( url );
};

However, I keep getting undefined as my latitude and longitude. I read somewhere that if you want to use the coordinates that you have to save them in the callback function of getCurrentPosition which is what I did but I'm still unable to get anything other than undefined. Is there a way to make these values accessible to my other functions?

I'm working on a basic JavaScript weather application. I'd like to pull the geolocation from the browser and make it accessible to my other functions.

function Weather( options ) {

    this.apiKey = options.key;
    this.endpoint = options.endpoint;
    this.coordinates = {};
}

Weather.prototype.GetLocation = function( callback ) {
    if (navigator.geolocation)
    {
        navigator.geolocation.getCurrentPosition( function(position) {
            this.coordinates.latitude = position.coords.latitude;
            this.coordinates.longitude = position.coords.longitude;
        });
    }
};

Weather.prototype.GetCurrentConditions = function() {

    this.GetLocation();

    var url = this.endpoint + "weather?lat=" + this.coordinates.latitude + "&lon=" + this.coordinates.longitude;

    return this.getJSONP( url );
};

Weather.prototype.GetExtendedForecast = function() {

    this.GetLocation();

    var url = this.endpoint + "forecast/daily?lat=" + this.coordinates.latitude + "&lon=" + this.coordinates.longitude + "&cnt=7";

    return this.getJSONP( url );
};

However, I keep getting undefined as my latitude and longitude. I read somewhere that if you want to use the coordinates that you have to save them in the callback function of getCurrentPosition which is what I did but I'm still unable to get anything other than undefined. Is there a way to make these values accessible to my other functions?

Share Improve this question asked Feb 9, 2016 at 4:57 PallasPallas 1,5895 gold badges27 silver badges59 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8 +50

Firstly, navigator.geolocation.getCurrentPosition callback works asynchronously, so you won't get results right after calling this.GetLocation(). Also, user can forbid to share his location with an application.

Secondly, you have a mistake with this. You need to pass context to callback here:

navigator.geolocation.getCurrentPosition( function(position) {
    // "this" doesn't equal to instance of your Weather class
    this.coordinates.latitude = position.coords.latitude;
    this.coordinates.longitude = position.coords.longitude;
});

For example, you can use .bind(this) to pass expected context to callback:

navigator.geolocation.getCurrentPosition( function(position) {
    this.coordinates.latitude = position.coords.latitude;
    this.coordinates.longitude = position.coords.longitude;
}.bind(this));

My solution

It's better to use Promise for async code. You can use any implementation of Promise, I prefer JQuery.deferred

My code is:

var getCurrentPosition = function() {
  var deferred = $.Deferred();

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject);
  } else {
    deferred.reject({
      error: 'browser doesn\'t support geolocation'
    });
  }

  return deferred.promise();
};

How to use it

var userPositionPromise = getCurrentPosition();

userPositionPromise
  .then(function(data) {
    // do whatever you want with geolocation data
  })
  .fail(function(error) {
    // show error for user
  });

You can use userPositionPromise as long as you want, it will be as container for user position data, you don't need to call getUserPosition again. To access to data, you need to call .then(callback) for your userPositionPromise variable.

本文标签: javascriptMaking geolocation coordinates available to other functionsStack Overflow