Search code examples
javascriptdartdart-js-interop

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


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.