1

This is PhoneGap application, but I think it is irrelevant here. So here is code I am using:

function Geolocation(){

    this.maximumAge = 3000;
    this.timeout = 20;
    this.enableHighAccuracy = true
    this.geolocation = navigator.geolocation.getCurrentPosition(this.onSucess, this.onError, {maximumAge : this.maximumAge, timeout : this.timeout, enableHighAccuracy: this.enableHighAccuracy});
}

Geolocation.prototype.onSucess = function(position){
}

Geolocation.prototype.onError = function(error){
    alert( typeof this.onSucess );
}

and whenever onError is triggered this alert returns undefined. Why is it happening?

0

3 Answers 3

2

Because this.onError is not called with the right context. You can try Function.bind():

navigator.geolocation.getCurrentPosition(
    this.onSucess.bind(this), 
    this.onError.bind(this),
    //...

The same goes for onSuccess.

Sign up to request clarification or add additional context in comments.

2 Comments

This is correct answer! I will mark it soon. Thanks! Does it have any "side effects"?
Nope, except that some browsers needs a shim for Function.prototype.bind (like IE8-). You’ll find more info and code here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
1

Besides the fact that success is spelled wrong, there is no way to be certain yet.

The tricky thing about JavaScript's use of "this" is that "this" is not determined by the method's definition but by how it is invoked.

I explained this recently in another similar question:

How the "this" affected in a method's method?

For example, I can define a variable that points to your function:

var blah = this.onSucess;
blah();  // "this" will be undefined

var bleh = {
  test: this.onSuccess
}
bleh.test();  // "this" will be the object literal.

When getCurrentPosition calls your callback function, it probably just calls it directly:

onSuccess(position);

therefore "this" is not defined.

What you can do is pass it a wrapper/proxy function that has a closure reference back to your Geolocation object so it can call this.onSuccess:

function Geolocation(){
    this.maximumAge = 3000;
    this.timeout = 20;
    this.enableHighAccuracy = true
    this.geolocation = navigator.geolocation.getCurrentPosition(function (position) {
          this.onSucess(position);
      },
      function (error) {
          this.onError(error);
      },
      {
       maximumAge : this.maximumAge,
       timeout : this.timeout,
       enableHighAccuracy: this.enableHighAccuracy
      });
}

A short-hand way to do this, as shown by David, is to use Function.bind, which returns a wrapper function doing just what I described, like so:

function Geolocation(){
    this.maximumAge = 3000;
    this.timeout = 20;
    this.enableHighAccuracy = true
    this.geolocation = navigator.geolocation.getCurrentPosition(this.onSucess.bind(this),
      this.onError.bind(this),
      {
       maximumAge : this.maximumAge,
       timeout : this.timeout,
       enableHighAccuracy: this.enableHighAccuracy
      });
}

Comments

0

this.onError is running in another context. it is running in context of navigator.geolocation.

If you want to run this.onError in context of Geolocation, you have to use a proxy method like this:

proxy = function(func, context) {
     func.apply(context);   
}

usage:

proxy(this.onError, this)

as example see this:

http://jsfiddle.net/Z32BZ/

have a nice day :-)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.