0

I've a custom LWC (Lightning Web Component) built to be used for a community (or Digital Experience). The component can be put on a Home Page or a Community Record Page.

I've few properties that within Community Builder can be set while publishing the component in the community.

These properties when set makes the component cause this error: Community component rendering error

This error only occurs when I chose to select a value from Identifier property, if I leave it empty then it works and displays fine.

This is how my test component rendering when I keep Identifier value as empty selection: enter image description here

Here is the component code:

myCommunityCmp.html

<template>
    recordId: {recordId}<br/>
    objectApiName: {objectApiName}<br/>
    identifier: {identifier}<br/>
</template>

myCommunityCmp.js

import { LightningElement, api, track, wire } from "lwc";

export default class MyCommunityCmp extends LightningElement {
    @api recordId;      //current context > record id
    @api objectApiName; //current context > sObject API Name
    @api identifier;
    
    connectedCallback() {
        console.log('Connected Callback');
    }
    renderedCallback() {
        console.log('Rendered Callback');
    }
    errorCallback(error, stack) {
        console.log('error callback', error);
        console.log('error callback [stack]', stack);
    }
}

myCommunityCmp.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <masterLabel>Custom Community Cmp</masterLabel>
    <isExposed>true</isExposed>
    <targets>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightningCommunity__Default">
            <property name="identifier" type="String" datasource="apex://IdentifierController" label="Identifier" default="" description="Enter a unique value to differentiate this instance from others on the page"/>
            <property name="recordId" type="String" label="Record Id" description="Automatically bind the page's record id to the component variable" default="{!recordId}" />
            <property name="objectApiName" type="String" label="Object Name" description="Automatically bind the page's object name to the component variable" default="{!objectApiName}" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

APEX Class to generate Identifier picklist values: IdentifierController.cls

global class IdentifierController extends VisualEditor.DynamicPickList {
    VisualEditor.DesignTimePageContext context;
    global IdentifierController(VisualEditor.DesignTimePageContext context) {
        this.context            = context;
    }

    global override VisualEditor.DataRow getDefaultValue(){
        /*VisualEditor.DynamicPickListRows values = getValues();
        if (values != null && values.size() > 0) {
            return values.get(0);
        }
        return null;*/
        return new VisualEditor.DataRow('-- Pick a value here --', '');
    }
    
    global override VisualEditor.DynamicPickListRows getValues() {
        VisualEditor.DynamicPickListRows  myValues  = new VisualEditor.DynamicPickListRows();
        myValues.addRow( new VisualEditor.DataRow('-- Pick a value here --', '') );
        String identifierId     = 'BE-';
        if (context != null) {
            if (!String.isBlank(context.entityName)) {
                identifierId        += Schema.getGlobalDescribe().get(context.entityName).getDescribe().getLabel();
            }
            if (!String.isBlank(context.pageType)) {
                identifierId        += context.pageType;
            }
            identifierId            = identifierId.trim().replaceAll('(\\s+)', '');
        }
        for (integer i=0; i<15; i++) {
            string picklistValue = identifierId + '-' + (i+1);
            myValues.addRow( new VisualEditor.DataRow(picklistValue, picklistValue) );
        }
        return myValues;
    }
}

The steps to reproduce are simple:

  • Have a Community and generate Object Pages for an object, say, Contact object.
  • Switch to Contact Detail community page within Community Builder.
  • Put this LWC Component on the Page anywhere.
  • The component will render without any issue, all the Console.log calls are called in browser console.
  • Select the component and in component properties dialog change Identifier picklist to any value.
  • The component will now fail to render, and notice that connectedCallback, renderedCallback, or errorCallback - none will be called. There would be nothing in the Debug Logs as well pointing to any error of any kind.

The code seems very simple to me, doesn't look like it should cause any error, but I'm unable to get past this issue. Could this be a Potential Community Bug?

1 Answer 1

1

Definitely looks like a bug.

It does not fail for me in Home page, as the context does not return any information for the picklist, so the picklist values are always the same

In record pages, it uses the context to build the picklist like 'BEContactCommRecordPage1, BEContactCommRecordPage2...' etc values.

When you change the identifier value, the getValues() method is called again to build again the picklist, and suddenly the values returned are not the same as before, because the context is null:

DesignTimePageContext:[entityName=null, pageType=null]

Before, it was not null

DesignTimePageContext:[entityName=Contact, pageType=CommRecordPage]

I tried everything to avoid getValues() to be called each time I change the 'identifier' value, and here is the solution; Implement an override for isValid():

global override boolean isValid(Object attr) {
    return true;
}

This will avoid to call getValues() each time you change.

Source: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_config_for_app_builder_dynamic_picklists.htm

Another possible but ugly solution is to build these identifiers with custom metadata so that they are not built dynamically but hard coded, and then choose each identifier for each component on purpose (as I guess this should be an admin task)

7
  • I tried to cache the response: salesforce.stackexchange.com/questions/365565/… but as it's said in this thread, the getValues() is called independently several times. Commented Nov 6, 2022 at 17:10
  • The problem does not limit itself to just Identifiers, the code I've posted here is very simplified version, I've got some 3-4 other dynamic properties that dynamically detect metadata and load content, not just identifier, and all are showing same issue. Selecting a value in those properties is causing the component to not render at all, same way
    – VarunC
    Commented Nov 6, 2022 at 20:51
  • @VarunC I edited my answer. With isValid() override now you won't have the issue. Commented Nov 7, 2022 at 7:44
  • This is so sweet. thank you @Luisma! I've not seen or read about isValid() override before in the docs from aura component frameworks. Also, would this cause issue if same component is used outside Digital Experience?
    – VarunC
    Commented Nov 7, 2022 at 8:46
  • isValid() seems to have broken the component on the Community Home Page now. I get following error link when I place the component on Home Page and the list of Identifier picklist is very strange now - link. Seems like picklist is generated twice but with different context in same execution.
    – VarunC
    Commented Nov 7, 2022 at 10:56

You must log in to answer this question.

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