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

The custom element constructor did not produce the element being upgraded #760

Closed
mseddon opened this issue Apr 16, 2017 · 5 comments
Closed

Comments

@mseddon
Copy link

mseddon commented Apr 16, 2017

Initially posted on Stack Overflow

I'm running into trouble getting a simple web component to work when transpiled to ES5. It appears to function perfectly fine under Chrome, Edge, and Firefox, but IE11 is failing in the component's constructor with "The custom element constructor did not produce the element being upgraded."

Where have I gone wrong?

The original source (in TypeScript):

import "./AppDrawer.less"

class AppDrawer extends HTMLElement {
    get open() {
        return this.hasAttribute("open");
    }

    set open(val: boolean) {
        val ? this.setAttribute("open", '') : this.removeAttribute('open');
    }

    get disabled() {
        return this.hasAttribute("disabled");
    }

    set disabled(val: boolean) {
        val ? this.setAttribute("disabled", '') : this.removeAttribute('disabled');
    }

    static get observedAttributes() { return ["open"] };

    constructor() {
        super();
    }

    connectedCallback() {
        this.addEventListener("click", () => {
            this.open = !this.open;
        })
        this.textContent = this.open ? "OPEN": "CLOSED";
    }

    attributeChangedCallback(attr, oldVal, newVal) {
        this.textContent = this.open ? "OPEN": "CLOSED";
    }
}


customElements.define("app-drawer", AppDrawer)

The output (bundle.js):

(function () {
'use strict';

function __$styleInject(css) {
    if (!css) return;

    if (typeof window == 'undefined') return;
    var style = document.createElement('style');
    style.setAttribute('media', 'screen');

    style.innerHTML = css;
    document.head.appendChild(style);
    return css;
}

__$styleInject("app-drawer {\n  color: red;\n}\n");

function __extends(d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

var AppDrawer = (function (_super) {
    __extends(AppDrawer, _super);
    function AppDrawer() {
        _super.call(this);
    }
    Object.defineProperty(AppDrawer.prototype, "open", {
        get: function () {
            return this.hasAttribute("open");
        },
        set: function (val) {
            val ? this.setAttribute("open", '') : this.removeAttribute('open');
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AppDrawer.prototype, "disabled", {
        get: function () {
            return this.hasAttribute("disabled");
        },
        set: function (val) {
            val ? this.setAttribute("disabled", '') : this.removeAttribute('disabled');
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AppDrawer, "observedAttributes", {
        get: function () { return ["open"]; },
        enumerable: true,
        configurable: true
    });
    
    AppDrawer.prototype.connectedCallback = function () {
        var _this = this;
        this.addEventListener("click", function () {
            _this.open = !_this.open;
        });
        this.textContent = this.open ? "OPEN" : "CLOSED";
    };
    AppDrawer.prototype.attributeChangedCallback = function (attr, oldVal, newVal) {
        this.textContent = this.open ? "OPEN" : "CLOSED";
    };
    return AppDrawer;
}(HTMLElement));
customElements.define("app-drawer", AppDrawer);

}());

And my HTML:

<!doctype html>
<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.0-rc.8/webcomponents-lite.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.0-rc.8/custom-elements-es5-adapter.js"></script>
        <script src="bundle.js"></script>
    </head>
    <body>
        <app-drawer open disabled></app-drawer>
    </body>
</html>
@mseddon
Copy link
Author

mseddon commented Apr 18, 2017

Update: removing custom-elements-es5-adapter.js and adding native-shim.js from https://github.com/webcomponents/custom-elements before bundle.js gets me to a state where ES5 works on chrome, ff, and edge, but IE11 is still failing with the same error.

@sanjeevpande
Copy link

sanjeevpande commented Mar 27, 2018

Hi @mseddon, I am getting same error, any update on this ?

@mseddon
Copy link
Author

mseddon commented Mar 30, 2018

@sanjeevpande I'm afraid I haven't got much more on this than the Stack Overflow issue linked above, but there is a workaround posted there. The issue appears to be related to Typescript transpiling classes to ES5 differently from e.g. babel, which seems to cause grief. The 'right' solution (my answer posted there) is to get Typescript to compile to ES6, then transpile down to ES5 with babel, but the accepted answer 'magically' fixes it if you want to take the risk that weird stuff might be happening underneath :)

@sanjeevpande
Copy link

Hi @mseddon, the issue is now fixed. The dom-module not loaded fully and the component was referenced in the html before that. This was resulting in this error. By the way, I am using custom-elements-es5-adapter.js with ES5. Thanks.

@TimvdLippe
Copy link
Contributor

This was an upstream issue in TypeScript (microsoft/TypeScript#7574) for which we now have reenabled our tests (webcomponents/custom-elements#151) which assert that ES5-output of TypeScript work correctly (https://github.com/webcomponents/custom-elements/blob/2b63886b2955c10ae7e322fe1ef7b954a13ad11e/tests/js/typescript.js)

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

3 participants