6

1. Context

Creating Web Components is possible in vanilla JS by:

  1. Creating a class that extends HTMLElement
  2. And then registering it:
    window.customElements.define('app-drawer', AppDrawer);
    

Since I have a lot of code in Dart I thought I could maybe do that with it. But I've hit some obstacles. Mainly the facts that document.registerElement() is deprecated and that window.customElements.define() doesn't seem to work.

I mostly use Microsoft Edge as a browser. But it uses Chromium anyway. And I've also tested everything mentioned below on Chrome as well.

2. What I've Tried

2.1. Günter's Answer with document.registerElement()

Günter's answer points to this dartpad, which uses the document.registerElement() to define it.

His answer does work, but document.registerElement() is deprecated:

document.registerElement is deprecated and will be removed in M80, around February 2020. Please use window.customElements.define instead.

Or at least on my computer it works, because his DartPad actually gives back the error of NoSuchMethodError: method not found: 'registerElement'

2.2 Trying the same thing with window.customElements.define()

My DartPad

My Gist

import 'dart:html';

main() {
  try {
    window.customElements.define('graph-button', GraphButton);
    final GraphButton button = GraphButton();
    document.body.append(button);
    button.changeInnerHtml();
  } catch (e) {}
}

class GraphButton extends HtmlElement {
  static const String tag = 'graph-button';

  factory GraphButton() => Element.tag(GraphButton.tag);

  GraphButton.created() : super.created();

  changeInnerHtml() => innerHtml = 'foo';
}

The code above will yield the following error message:

Error: Failed to execute 'define' on 'CustomElementRegistry': The callback provided as parameter 2 is not a function.

2.3. An Attempt with JS Interop

I've even tried to create an interop function for JS's window.customElements.define, but the error was the same.

@JS('window.customElements')
library web_components_interop;

import 'package:js/js.dart';

@JS('define')
external void registerWebComponent(String name, Object constructor, [Map<dynamic, dynamic> options]);

Then simply replacing the registering above for registerWebComponent(GraphButton.tag, GraphButton); will now yield the same error message.

3. Other Helpful Resources

Is there official documentation on this topic? I was hoping to find something about it on AngularDart's docs — since, in Angular, creating web components is quite common —, but I haven't been able to so far.

Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76
  • It has to be `class GraphButton extends HTMLElement`, not `class GraphButton extends HtmlElement`. – connexo Oct 25 '20 at 19:55
  • 1
    But the `HTMLElement` doesn't seem to exist in Dart, or at least not under `dart:html`. The `HtmlElement` class is even marked as coming from JS's `HTMLElement`: `@Native("HTMLElement")`. – Philippe Fanaro Oct 25 '20 at 20:00
  • can I ask you please ? Do you think that AngularDart is good framework to build a website ? I have worked a bit with Flutter but it's difficult for me because I am used to work with html, css , js ... I see Angular (typeScript) is more popular than AngularDart , but what is your opinion ? Thanks – hous Nov 16 '20 at 09:34
  • HTML and CSS are great for static content. And most of the content in most apps is text, so that's why they work so well to this day. But doing animations and transitions is kind of a pain in the ass with them. So that's where Flutter finds its place. I think there's still a documentation page on dart.dev where they say explicitly that, if your content only uses text and is on the web, just use HTML and CSS. – Philippe Fanaro Nov 16 '20 at 12:18
  • 1
    With regards to AngularDart, Google uses it intensely in their backend. In fact, [the whole GoogleAds app and web apps is done with AngularDart](https://www.youtube.com/watch?v=0mHspoS5Zf8&list=PLOU2XLYxmsIIJr3vjxggY7yGcGO7i9BK5&index=19), it was their first milestone in terms of proving it could be used for big apps. The problem is that it never gained much traction with the public. Personally, if I'm gonna develop for the web and/or use Angular, I would simply use TS because it's so much easier to find info and make things work. And Dart's limitations are much less clear. – Philippe Fanaro Nov 16 '20 at 12:24

0 Answers0