2

This week I noticed that two of a customer's sandboxes started to fail to load LWC components that have a property named tagName on them. It fails with a message like cannot set property because only have get.

I can assume it is related to Element.tagName, but I could not find anywhere (including LWC docs) that this is supposedly a reserved keyword for LightningElement.

Have you faced a similar problem? Is this documented, and have I missed it?

What also amuses me is the behaviour inconsistency.

Note: I found a blog post from Brett M. Nelson while writing this question.

2
  • 1
    Seems to me you could cite that blog entry in an answer that takes the key points from it.
    – Phil W
    Commented Feb 24, 2023 at 19:39
  • 2
    @PhilW I'll do one better :D
    – sfdcfox
    Commented Feb 24, 2023 at 19:50

1 Answer 1

7

The LightningElement class extends a class called HTMLElementTheGoodPart, which in turn is imbued with HTMLElement.prototype properties through the BaseBridgeElement. As you may know, or might guess, HTMLElement is extended from Element, so it has the same properties as an Element.

If you look at the TypeScript definition for HTMLElementTheGoodPart, you'll see this:

class HTMLElementTheGoodPart {
    // ... Other stuff
    readonly tagName: string;
    readonly classList: DOMTokenList;

Both of these properties are meant to be read-only. It's likely that a bug that previously allowed writing to these properties were fixed.

As a general rule, you should imagine that your LightningElement is an extension of HTMLElement, and those properties should be considered reserved. If you want to set one of these values, you can use this.setAttribute, as described in Reflect JavaScript Properties to HTML Attributes.

You can still technically use these properties, but only as a read-only property. In other words, @api tagName is technically allowed, but that only lets you read the tagName property. That's why the error mentions that there is no "set" method.

As such, I'd say that this is definitely a documentation bug. The new observed behavior is correct, as you'd not be able to set tagName on normal HTML elements, either.

The blog post you mentioned appears to have all of the values that are forbidden. Any property in HTMLElement or Element is likely to be read-only or inaccessible, depending on HTMLElementTheGoodPart.

3
  • Thanks a million sfdcfox, yeah, I think this is correct, but what strikes me is that is not documented as you explained nor it breaks consistently (it seems that Salesforce become more strict on this case but only on certain environments). Commented Feb 24, 2023 at 20:47
  • 1
    @JefersonChaves A lot of LWC was built on polyfills previously. As things become more native, expect things to become more strict. I'll contact the doc team later about this as well. I agree the docs should agree with reality.
    – sfdcfox
    Commented Feb 24, 2023 at 20:54
  • Fair enough, I suppose that now that we are moving towards LWS and away from Locker it will be more strict. I also hope the LWC compiler throws an error on such cases (I prefer let things burn instead of swallowing the error and wait for a runtime error). Commented Feb 24, 2023 at 21:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .