JsFunction.apply doesn't work while JsObject.callMethod does work (dart)

Issue

I have this often, that JsFunction.apply doesn’t work like I would expect. Consider this example:

import "dart:js";
import "dart:html";

void main() {
  var div = querySelector('div');
  var span = new SpanElement()..text = "hello world";
  var js = new JsObject.fromBrowserObject(div);
  js["appendChild"].apply([span]);

  // this one does work:
  // js.callMethod("appendChild", [span]);
}

I would expect that js["appendChild"].apply([span]); to work exactly the same as js.callMethod("appendChild", [span]);.

See also this demo: https://dartpad.dartlang.org/0f35d76a3c61ba1371f1

Solution

It works with js["appendChild"].apply([span], thisArg: js);

If you don’t provide thisArg it’s like you call Function.prototype.apply with null as first argument.

Thus your Dart call is the same as the js :

var div = document.querySelector('div');
var span = document.createElement("span");
span.innerText = "hello world";
div["appendChild"].apply(null, [span]);

The execution of above js code leads to a TypeError: Illegal invocation. To make it work you have to use div["appendChild"].apply(div, [span]);.

So it was not a Dart issue but rather a js issue.

Answered By – Alexandre Ardhuin

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.