Sdk: dart:html - dartdevc `getCurrentLocation` throws

Created on 19 Mar 2018  路  9Comments  路  Source: dart-lang/sdk

In chrome, with device emulation on, the following snippet throws dart_sdk.js:31102 Uncaught TypeError: geoloc[$getCurrentPosition] is not a function when trying to access window.navigator.geolocation.getCurrentPosition

Dart VM version: 2.0.0-dev.39.0 (Fri Mar 16 00:17:07 2018 +0100) on "linux_x64"

Update: dart2js version work as expected

import 'dart:async';
import 'dart:html';

import 'dart:js';

Future main() async {
  JsObject jsNav = context['navigator']['geolocation'];
  window.console.info(jsNav['getCurrentPosition']);
  window.console.info(jsNav['getCurrentPosition'] is JsFunction);
  var geoloc = window.navigator.geolocation;
  var pos = await geoloc.getCurrentPosition(maximumAge: new Duration(seconds: 0), timeout: new Duration(seconds: 0));
}

Console output:

js.JsFunction._fromJs聽{Symbol(_jsObject): 茠}
true
Uncaught TypeError: geoloc[$getCurrentPosition] is not a function

Compiled code:

  const $getCurrentPosition = dartx.getCurrentPosition;
  main.main = function() {
    return async.async(dart.dynamic, function* main() {
      let jsNav = js.JsObject._check(dart.dindex(js.context._get('navigator'), 'geolocation'));
      html.window[$console].info(jsNav._get('getCurrentPosition'));
      html.window[$console].info(js.JsFunction.is(jsNav._get('getCurrentPosition')));
      let geoloc = html.window.navigator.geolocation;
      let pos = (yield geoloc[$getCurrentPosition]({maximumAge: new core.Duration.new({seconds: 0}), timeout: new core.Duration.new({seconds: 0})}));
    });
  };
area-web library-html web-dev-compiler

Most helpful comment

Until I get some extra info on what's going on here, here is something that might help people:

https://gist.github.com/daniel-v/4ef77795599888c36ec144c941b6ca68

Hackish but works with ddc and dart2js

All 9 comments

Until I get some extra info on what's going on here, here is something that might help people:

https://gist.github.com/daniel-v/4ef77795599888c36ec144c941b6ca68

Hackish but works with ddc and dart2js

@terrylucas - we might be missing a registerExtension on the geolocation class.

Same happens with window.navigator.geolocation.watchPosition()

With this example you'll get the same error:

if (window.navigator.geolocation != null) {
      window.navigator.geolocation.getCurrentPosition().then((geoPosition) {
        print(geoPosition.coords.latitude.toString() +
            "," +
            geoPosition.coords.longitude.toString());
      });

      window.navigator.geolocation.watchPosition().listen((geoPosition) {
        print(geoPosition.coords.latitude.toString() +
            "," +
            geoPosition.coords.longitude.toString());
      });
    }

Tested on:

Dart VM version: 2.1.0-dev.4.0 (Fri Sep 7 16:44:38 2018 +0200) on "macos_x64"

This is not worth an update?

final dom.Geolocation geo = dom.window.navigator.geolocation;
final dom.Geoposition position = await geo.getCurrentPosition(
                    timeout: new Duration(seconds: 5));

Tested on:

Dart VM version: 2.1.0 (Tue Nov 13 18:22:02 2018 +0100) on "macos_x64"

@MikeMitterer I am a tad confused what you tested.

I did a copy-paste test run with your code and I experienced the following:

dart2js compiled script works as expected
ddc still throws the same error: Uncaught TypeError: geo[$getCurrentPosition] is not a function

DDC generates the following js

return async.async(dart.dynamic, function* main() {
      let geo = html.window.navigator.geolocation;
      let position = (yield geo[$getCurrentPosition]({timeout: new core.Duration.new({seconds: 5})}));
      html.window[$console].info(position.coords);
    });

@terrylucas @jmesserly - do we need to inject promise / future conversion here?

do we need to inject promise / future conversion here?

if it's not finding the method at all, that suggests a failure to install the extension methods on the prototype.

Indeed, it appears window.Geolocation is not defined, so this line of the SDK will not work: dart.registerExtension("Geolocation", html$.Geolocation);

I believe this is a difference in how the @Native is interpreted; for dart2js it needs to be a string that matches the constructor name (it's slightly more complex, but that's the rough idea), for dartdevc it needs to be a JS expression that provides access to the constructor function relative to the global object.

I'm not sure how y'all have been solving these issues in the past. Conceptually, navigator.geolocation.constructor seems to provide the constructor that DDC is looking for.

I have an issue with dart2js.
In DDC, script works like a charm, but doesn't in Dart2JS.

https://dartpad.dartlang.org/1bc314a9a437281cf263fb54e2b57537

Uncaught Error: TypeError: Instance of 'GeolocationPositionError': type 'UnknownJavaScriptObject' is not a subtype of type 'PositionError'
or
Uncaught Error: TypeError: Instance of 'GeolocationPosition': type 'UnknownJavaScriptObject' is not a subtype of type 'Position', if geolocation is enabled in browser.

Was this page helpful?
0 / 5 - 0 ratings