Skip to content
This repository has been archived by the owner on Sep 20, 2019. It is now read-only.

Error: The custom element being constructed was not registered with customElements. in firefox #809

Closed
yannickl88 opened this issue Jul 13, 2017 · 7 comments

Comments

@yannickl88
Copy link

yannickl88 commented Jul 13, 2017

I get this odd error when using both the ES5 adapter and the loader using firefox.

My HTML file:

<html>
<head>
    <script type="text/javascript" src="/js/custom-elements-es5-adapter.js"></script>
    <script type="text/javascript" src="/js/webcomponents-loader.js"></script>
</head>
<body>
<fancy-button></fancy-button>

<script>
    function FancyButton() {
        HTMLElement.call(this);
        this.innerHTML = 'FOOBAR';
    }

    FancyButton.prototype = Object.create(HTMLElement.prototype);
    
    window.customElements.define('fancy-button', FancyButton);
</script>

</body>
</html>

When loading the page no output is shown and in the console I get:

Error: The custom element being constructed was not registered with `customElements`.

This happends in the file webcomponents-hi-sd-ce.js:45:511 (minimized).

Using firefox 54.0 (64-bit) on Ubuntu 14.04.

This error does not occur in Chrome, where everything seems to work fine.

EDIT: simplified example a bit

@yannickl88
Copy link
Author

yannickl88 commented Jul 13, 2017

Small update, on a windows PC now. Same error still on firefox 54.0.1 on Windows 10. Also happens in IE 11.0.43 (version 11.1358.14393.0) and Edge 38.14393.1066.0.

So this is more commonplace than just firefox.

@HendrikThePendric
Copy link

I got here via #811 and tried to replicate the example provided by @yannickl88. The example is valid reproduction path, but contains a small error. Before defining the customElement, you need to wait for the webcomponents ready event. I think Yannick went a bit overboard simplifying his example :-)

window.addEventListener('WebComponentsReady', function () {
    window.customElements.define('fancy-button', FancyButton);
});

In my situation I am getting a TypeError: a.__shady is undefined when adding elements to the page.

@anirban-dutta
Copy link

It worked for me the preset bundled build, after disabling MINIFY for html for Firefox. Chrome it was working fine.Problem faced by me even with the Polymer 2 starter kit.
Sample:
{
"name": "bundled-es6",
"preset": "es6-bundled",
"html": {"minify": false}
}

@bicknellr
Copy link
Contributor

Hi, there's a couple of issues with the provided example that are preventing this from working:

function FancyButton() {
  // The result of your `super()` replacement needs to be used as if it were `this`.
  // However, it also needs to default to the real `this` in case it doesn't explicitly
  // return something.
  var _this = HTMLElement.call(this) || this;

  /* ... do stuff with `_this` as if it were `this` ... */

  requestAnimationFrame(function() {
    // This was moved into a `requestAnimationFrame` callback because you can't
    // modify descendants or attributes in the constructor itself.
    _this.innerHTML = 'FOOBAR';
  });

  // You need to return `_this` so that any extensions to `FancyButton` will use it.
  return _this;
}

FancyButton.prototype = Object.create(HTMLElement.prototype);

// The custom elements polyfill needs `X.prototype.constructor === X` to be
// true for any custom element constructor `X` so that it can figure out what
// the constructor was and look up the associated definition. This is true by
// default but the line above creates a new object without its own `constructor`
// property. i.e. Before the next line, `FancyButton.prototype.constructor`
// would return `HTMLElement`.
FancyButton.prototype.constructor = FancyButton;

// As @HendrikThePendric mentioned, this needs to be wrapped in a listener for
// the 'WebComponentsReady' event so that the loader can load the specific
// polyfills you need before you start using them.
window.addEventListener('WebComponentsReady', function() {
  window.customElements.define('fancy-button', FancyButton);
});

This link (a babel repl) might be helpful for seeing why the _this thing is needed and why I decided to use that variable name :) . Roughly, it's the closest approximation to super() for constructors that transpilers can produce. The other thing about custom-elements-es5-adapter.js is that your extensions to HTMLElement when using it must all be ES5 class-like constructors - you can't compile only a portion of your classes while using it.

@bicknellr
Copy link
Contributor

@yannickl88, were you able to clear up the issue you were running into?

@yannickl88
Copy link
Author

Sorry for the late reply, I did not yet have time to verify before. Just checked Chrome, FF, IE and edge and your example indeed works!

Bit of a shame it doesn't work with the 'standard' ES5 way of defining objects.

For those wondering, the full (working) example would be:

<html>
<head>
    <script type="text/javascript" src="webcomponentsjs/custom-elements-es5-adapter.js"></script>
    <script type="text/javascript" src="webcomponentsjs/webcomponents-loader.js"></script>
</head>
<body>
<fancy-button></fancy-button>

<script>
    function FancyButton() {
        var _this = HTMLElement.call(this) || this;

        requestAnimationFrame(function() {
            _this.innerHTML = 'FOOBAR';
        });

        return _this;
    }

    FancyButton.prototype = Object.create(HTMLElement.prototype);
    FancyButton.prototype.constructor = FancyButton;

    window.addEventListener('WebComponentsReady', function() {
        window.customElements.define('fancy-button', FancyButton);
    });
</script>

</body>
</html>

Closing this since it is has been resolved as far as I am concerned.

@bicknellr
Copy link
Contributor

Yeah, it's a bit unusual, but it falls out of the way that ES2015 classes have to be extended in ES5 and that extensions to HTMLElement have to use ES2015-only features (if you're not this adapter). Here's a link to a related explanation in the custom elements polyfill. Anyway, thanks for letting me know this worked!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants