JS Object.create() in Dart - dart

I'm constructing two JS object in Dart. In JS, they are constructed with Object.create():
var wavesurfer1 = Object.create(WaveSurfer);
var wavesurfer2 = Object.create(WaveSurfer);
This is what I think is Dart equivalent:
var wavesurfer1 = context['WaveSurfer'];
var wavesurfer1 = context['WaveSurfer'];
But, I found that the two objects in Dart appear to be the same. When I call a function in one object it gets triggered in both. This does not happen in the JS code. I suspect that Object.create() should not be written as context[''] in Dart. If this is true, I'm not able to find an example in dartlang.org or stackoverflow.com for how to correctly translate this expression to Dart. You can see the JS source code for WaveSurfer here.

With context['WaveSurfer'] you get a JsObject corresponding to the Js WaveSurfer and not to a new object.
To do the Dart equivalent of your pasted JS code :
import 'dart:js';
var wavesurfer = context['WaveSurfer'];
var wavesurfer1 = context['Object'].callMethod('create', [waveSurfer]);
var wavesurfer2 = context['Object'].callMethod('create', [waveSurfer]);
See Using JavaScript from Dart.
If you find the usage of dart:js to hard and verbose you can use package:js that provides a simplier API (but with a larger JS generated size) :
import 'package:js/js.dart';
var wavesurfer1 = context.Object.create(context.WaveSurfer);
var wavesurfer2 = context.Object.create(context.WaveSurfer);

Related

Returning anonymous JS function which returns javascript plain object from Dart

Dart Code
import 'dart:html' as html;
import 'dart:js' as js;
import 'package:js/js.dart';
void main() {
var data = new AddLocationData(locationName: "Location1", locationPath: "ThisFolder");
var func = () => data;
html.window.console.log(func);
html.window.console.log(func());
}
#JS("")
#anonymous
class AddLocationData {
external String get locationName;
external String get locationPath;
external factory AddLocationData({String locationName, String locationPath});
}
You would assume that func will be a js function but its not. Its type/name is main_closure. See the screenshot
So the first two lines were printed from Dart code then I used Chrome Inspect Element window and right clicked on main_closure' and selected "Store as global variable" which then printedtemp1` and then I used it to display some information about the generated code.
So it is clear Dart returned an object and not a js function and so is the reason of asking this question.
So I want temp1 to be a function instead of temp1.call$0 so that I can get the data by calling temp1() and not temp1.call$0().
See js package doc:
Passing functions to JavaScript.
If you are passing a Dart function to a JavaScript API, you must wrap it using allowInterop or allowInteropCaptureThis.

Export Dart classes and functions to javascript

If I want to use Dart to create a js library, how can I export Dart classes and functions for use in javascript?
Is there something similar to scala.js, like this?
#JSExport
class Hello{
num x = 0
Hello(this.x)
}
So that in javascript, users can instantiate it as var hi = new Hello(1)
In case this is still relevant: You can use the dart2js compiler, which will compile your dart code down to ES.

How to create a dynamic variable in dart

I am moving java script to dart, in java script I create dynamic variable like
window["text" + pageNumber] = 123;
alert(window["text" + pageNumber]);
How can I do it with dart?
In Dart Window (the type of window) is a class. You can't dynamically add properties to a Dart class.
window["text" + pageNumber] = 123; would work with a Map. Object representation in JS is quite similar to a map and therefore this works there.
If another class implements the [] operator you could call it on instances of that class as well but it would still not add properties. What it actually does just depends on the implementation of the [] operator.
There are probably different ways in Dart to achieve what you want, but you didn't add details about what actual problem you try to solve.
You can use normal global variables in Dart like explained in
Global Variables in Dart.
For your use case you can create a global Map variable this way
final Map<String,int> myGlobals = <String,int>{};
to create a map that stores integer values with string names.
Set values with myGlobals['someName'] = 123; and read them with print(myGlobals['someName']);.
If you need to set a global value that is also available for JS libraries you might use, you can use dart-js-interop
import 'dart:js';
import 'dart:html';
main() {
int pagenumber = 5;
context['Window']['text$pagenumber'] = 123;
window.alert('${context['Window']['text$pagenumber']}');
}
Try it on DartPad.
Hint:
"text" + pageNumber doesn't work when pageNumber is not a string.
In Dart you can't add string and numbers.
"text" + pageNumber.toString() would work but 'text$pagenumber' is a more darty way to do this. In string interpolation toString() is called automatically for you.
See also Dart js-interop not working if .dart file isn't included.

How do you interact with js from dart?

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.
http://dart-lang.github.io/js-interop/docs/js.html
https://api.dartlang.org/docs/channels/stable/latest/dart_js.html
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.
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']);
}

Web page Javascript and Extension (using js-ctypes) communication

I have written a extension which makes use of js-ctypes. I have a function in the extension binded by js-ctypes with a C library function. Now, I want to pass some data loaded from the web page to this C library via Extension (js-ctypes). How do i do it ?
I came across - https://developer.mozilla.org/en-US/docs/Code_snippets/Interaction_between_privileged_and_non-privileged_pages .
I understood the part where messages i.e strings are passed but now how do I use it pass data to my extensions' js-ctypes binded function from the web page ?
Precisely I am allocating a array in my web page js script. populate some data. Now I need to send this array/data to the C library function i.e invoke C lib function with this data
Communicate with your extension, send data as JSON (sometimes arrays are wrong serialized).
For example you can send event:
var obj = JSON.stringify({arg1: 3, arg2: "some text"});
var event = new CustomEvent("YourAddonEvent", { detail: obj });
top.dispatchEvent(event);
In extension parse JSON and you will get object with arguments.
var args = JSON.parse(event.detail);
After load library and declare function, e.g:
var func = lib.declare("YourFuncName", ctypes.default_abi, ctypes.int, ctypes.int, ctypes.char.ptr, );
you can invoke your function:
var result = func(args.arg1, args.arg2);

Resources