10

Is there currently a way of exposing properties inherited from super classes in Lightning Web Components, as design attributes (targetConfigs), or is this a gap? I’m inheriting base classes which themselves ultimately inherit from LightningElement but those which I’ve configured to display as design time attributes in the sub most class aren’t showing up in the editors.

  • Please could you edit your question and provide a code example of what your doing and what you'd like to achieve? – Robs Jan 28 '19 at 15:03
  • Welcome Dafydd! Does your sub class component have a meta file or are you expecting the meta file for the super component to be read? – citizen conn Jan 28 '19 at 15:18
10

tl;dr: Currently, this is a gap.

From the pure perspective of accessibility, @api enabled properties of a LWC are inherited from parent to child. This is standard JS prototype inheritance at work.

You've probably found this. But when setting the config for design attribute in the metadata file to be connected to an inherited property, you get the following error:

The 'propName' property doesn't exist on the component.

Here's a test case to try:

A parent LWC module, and for sake of simplicity, an empty template/markup file.

//parentInheritance.js
import { LightningElement, api } from 'lwc';

export default class ParentInheritance extends LightningElement {

  @api parentProp; 

}

A child LWC extending the parent component with a template referencing both its own prop, and the child.

//childInheritance.js
import { api } from 'lwc';
import ParentInheritance from 'c/parentInheritance';

export default class ChildInheritance extends ParentInheritance {

  @api childProp; 

}

//childInheritance.html
<template>
  <lightning-card>
    <p>{childProp}</p>
    <p>{parentProp}</p>
  </lightning-card>
</template>

Then we compose some UI on another component by sticking c/childInheritance component there, it works fine:

<template>
  <c-child-inheritance 
    child-prop="Child Value 1" 
    parent-prop="Parent Value 2">
  </c-child-inheritance>
</template> 

But when I attempt to add it to the app builder config section of my metadata file, I get the "property does not exist" error above. Here's what that would look like.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childInheritance">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__AppPage">
            <property name="parentProp" type="String"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

As a workaround, you could create a kind of proxy @api exposed property that you map to the meta config file.

export default class ChildInheritance extends ParentInheritance {

  @api childProp; 
  @api parentProxyProp;

  connectedCallback(){
    if (!this.parentProp) {
        this.parentProp = this.parentProxyProp;
    }
  }

}

Then you reference parentProxyProp in metadata.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childInheritance">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__AppPage">
            <property name="parentProxyProp" type="String"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

This has a side-effect, though: you now have a new property that's only meant as a pass-through to connect up the child to the parent prop. Someone could attempt to use it, so not perfect, and you'd need to plan for that accordingly.

This gap is known by the LWC team, but roadmap for when it will be addressed has not been announced.

| improve this answer | |
0

Remove "default" from parent JS file. Example : Instead of below:

export default class ParentInheritance extends LightningElement {
   @api
   parentProp;
}

Define as below without "default":

export class ParentInheritance extends LightningElement {
   @api
   parentProp;
}

Now, you can access parent properties & functions without creating any proxy. Just access them using "this". Example from child JS:

this.parentProp

Hope this information helps.

| improve this answer | |
  • Does this specifically allow me to expose as a design attribute on a sub component, an attribute that is defined on a super component? – Dafydd Johns Jul 23 '19 at 14:38
  • No. This will allow you to use the public api attributes/properties from the parent JS class in the child component's JS & HTML files. You can pass attribute values from the parent LWC container to child LWC's parent JS class attributes. Remember, by inheriting a class in the JS file you are inheriting properties and functions but NOT the UI. So the HTML template does not know where to use the property from parent class hence design attributes will not work. I believe this is by design from Salesforce and I agree with this architecture. You can follow @pchittum's suggestion as a solution. – Rahman Jul 23 '19 at 20:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.