Marc Teichtahl
Marc Teichtahl

Reputation: 311

Empty variables when calling javascript function

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

Answers (2)

Sai Prasad
Sai Prasad

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

Peter Sobot
Peter Sobot

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

Related Questions