Bluebird: Illegal invocation error with navigator.geolocation.getCurrentLocation

Created on 3 Aug 2016  路  4Comments  路  Source: petkaantonov/bluebird

1) What version of bluebird is the issue happening on?
3.4.1

2) What platform and version? (For example Node.js 0.12 or Google Chrome 32)
Opera 38

3) Did this issue happen with earlier version of bluebird?
Don't know, but some clues I've found by googling do indicate that people managed to run the same code I am trying to run.

Here is the simplest code example to test the issue: https://jsfiddle.net/akdog4r0/
Or the code here:

var getLocation = Promise.promisify(navigator.geolocation.getCurrentPosition);

getLocation().then(function(pos) {
    console.log(pos);
}).catch(function(err) {
    console.log(err);
});

Running this code throws TypeError: Illegal invocation and points to the getLocation() call. This happened also on some local app, js fiddle is just to illustrate the problem.

Most helpful comment

@vincaslt you have a couple of problems here, firstly that error is happening because you are treating a _method_ as if it were a _function_. The difference between the two is that a method cares about the value of this, which is being lost in this case.

Taking Bluebird completely out of the picture, the following will fail with the exact same error:

var getLocation = navigator.geolocation.getCurrentPosition;
getLocation(result => console.log(result)); // Illegal Invocation

You need to preserve the context, by adding a second argument to your promisify() call (Note: This won't actually work in your case, see below.)

var getLocation = Promise.promisify(navigator.geolocation.getCurrentPosition, navigator.geolocation);

getLocation().then(result => console.log(result)); // no illegal invocation error, but weird behaviour, WTF?

Your second issue is that getLocation() is a browser API and does not take a node style callback, so promisify() isn't going to work at all in this case! You need to fall back to the promise constructor:

function getLocation () {
  return new Promise(function (resolve, reject) {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
}

All 4 comments

Have a look at https://stackoverflow.com/questions/31639639/cant-apply-lodash-partial-to-function-created-with-bluebird-promisifyall, https://stackoverflow.com/questions/38577330/cannot-read-property-of-undefined-after-promise-promisify, https://stackoverflow.com/questions/32509904/how-to-ensure-correct-this-with-promise-promisify and many others :-)

Maybe I don't understand the problem clearly, but nothing that I've gathered from those articles have helped me to solve the problem...

getCurrentPosition is a method of the navigator.geolocation object, and like any other callback function you have to bind it to its context.

@vincaslt you have a couple of problems here, firstly that error is happening because you are treating a _method_ as if it were a _function_. The difference between the two is that a method cares about the value of this, which is being lost in this case.

Taking Bluebird completely out of the picture, the following will fail with the exact same error:

var getLocation = navigator.geolocation.getCurrentPosition;
getLocation(result => console.log(result)); // Illegal Invocation

You need to preserve the context, by adding a second argument to your promisify() call (Note: This won't actually work in your case, see below.)

var getLocation = Promise.promisify(navigator.geolocation.getCurrentPosition, navigator.geolocation);

getLocation().then(result => console.log(result)); // no illegal invocation error, but weird behaviour, WTF?

Your second issue is that getLocation() is a browser API and does not take a node style callback, so promisify() isn't going to work at all in this case! You need to fall back to the promise constructor:

function getLocation () {
  return new Promise(function (resolve, reject) {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

overlookmotel picture overlookmotel  路  5Comments

bripkens picture bripkens  路  4Comments

capaj picture capaj  路  5Comments

Shrivallabh picture Shrivallabh  路  3Comments

SimonSchick picture SimonSchick  路  6Comments