How do you interact with js from dart?

Issue

No, this isn’t the same as the other question of the same name.

There are seemingly identical packages which seem to do this, but with different apis.

Why are there two?

Which one are we supposed to use?

The interop one looks newer and has a better api, but doesn’t actually work. According to the documentation, you should be able to convert this javascript:

var stage = new PIXI.Stage(0xFFFFFF);;
renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);

Into:

var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
var renderer = js.context.PIXI.autoDetectRenderer(400, 400);
document.body.append(renderer.view);

But that errors when you try to compile it:

dart2js
Error occured:/Users/doug/megac/client/public/dart/index.dart:7:27:
Warning: No member named 'PIXI' in class 'Proxy'.
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
^^^^^^^^^^^^^^^

So… js:dart? Is that what you’re supposed to use?

Edit: Incidentally, for anyone who stumbles into this, there is also an open bug http://code.google.com/p/dart/issues/detail?id=15795&thanks=15795&ts=1388068177 regarding how minified dart-js interop bridge operations don’t currently work. The original issue was reported in May 2013, and there’s been no action on it since then, so don’t hold your breath.

Solution

Js interop started with package:js. It was built with with window.postMessage.

Later dart:js has been added to provide better performance and reduce the size of the compiled js file. Basically the goal were :

  • removing scopes and lifecycle manual handling
  • avoiding noSuchMethod to keep compilation size as low as possible
  • renaming objects to make the api more understandable

Once dart:js has been ready, package:js has been rewrite to use dart:js under the cover.

package:js provides a simpler Api that comes at the cost of an increase of the js size (because package:js uses dart:mirrors and noSuchMethod).

Here is the same thing done with package:js and dart:js :

import 'package:js/js.dart' as js;

main() {
  var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
  var renderer = js.context.PIXI.autoDetectRenderer(400, 400);
  document.body.append(renderer.view);
}

import 'dart:js' as js;

main() {
  var pixi = new js.JsObject(js.context['PIXI']['Stage'], [0xffffff]);
  var renderer = js.context['PIXI'].callMethod('autoDetectRenderer', [400, 400]);
  document.body.append(renderer['view']);
}

Answered By – Alexandre Ardhuin

Answer Checked By – Mildred Charles (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *