1

We have an aura component that is used on the app builder, the component uses the dynamic picklist on the app builder. The problem is when we drag the component on the lightning page and then select the options for the picklist and then save the page then the apex class which is used as data source for the design attribute called twice. So, when we drag multiple components on the same page then it hits the governor limit.

Let's take an example of the HelloWorld component to reproduce the issue.

Please see the code of HelloWorld.cmp (component file)

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome" access="global">
    <aura:attribute Name="accountId" Type="String" />
    <div>
        Helloe World!<br/>
        Accout Id: {!v.accountId}
    </div>
</aura:component>   

Now see the component design file HelloWorld.design:

<design:component  label="Test Component">
    
    <design:attribute name="accountId" label="Account" description="Select Account" datasource="apex://CDR_Account"/>
</design:component>

Now see the code of CDR_Account apex class which is used as datasource for the design attribute accountId:

global class CDR_Account extends VisualEditor.DynamicPickList{
    global CDR_Account() {

        System.debug('==>> Hey I am inside constructor');
    }

    global override VisualEditor.DataRow getDefaultValue(){
        VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('Select An Account', '');
        return defaultValue;
    }
    
    global override VisualEditor.DynamicPickListRows getValues() {
        
        list<account> listAccount =  [SELECT id, name FROM Account LIMIT 5];
        VisualEditor.DynamicPickListRows  goalRows = new VisualEditor.DynamicPickListRows();
        VisualEditor.DataRow newValue1 = new VisualEditor.DataRow('Select an Account','');
        goalRows.addRow(newValue1);
        for (Account acc : listAccount) {
            VisualEditor.DataRow newValue = new VisualEditor.DataRow(acc.name, '' + acc.id);
            goalRows.addRow(newValue);
        }
 
        return goalRows;
    }
}

As you can see in the CDR_Account class we are querying the account to get account as a picklist option.

Now when we drag this component on the lightning page and then select the account for this component from the picklist options and then save the lightning page, then we find in the debug log CDR_Account class called twice in a single transaction. So, it consumed two SOQL for a single component. So similarly when we drag more than 50 components on the same page then try to save the page then it throws error because it's exceeds the SOQL limit.

I have explained it with an example of dummy component, I am facing this issue for a real use cases. So, any help on this will be appreciated.

2 Answers 2

0

If you're querying the same values over and over again, you should cache them. I don't have time to set this up at the moment, but moving the variable to a static scope should help:

static list<account> listAccount =  [SELECT id, name FROM Account LIMIT 5];
global override VisualEditor.DynamicPickListRows getValues() {
    VisualEditor.DynamicPickListRows  goalRows = new VisualEditor.DynamicPickListRows();
    VisualEditor.DataRow newValue1 = new VisualEditor.DataRow('Select an Account','');
    goalRows.addRow(newValue1);
    for (Account acc : listAccount) {
        VisualEditor.DataRow newValue = new VisualEditor.DataRow(acc.name, '' + acc.id);
        goalRows.addRow(newValue);
    }

    return goalRows;
}
1
  • We can't use static because, when we drag the component on the page then data source classes (CDR_Account) are called in the independent separate transaction. Dec 21, 2021 at 16:40
0

A bit late, but it seems you need to add an extra method:

public boolean isValid(String attr) {
   return true;
}

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

  • isValid() runs in Experience Cloud sites when the page loads. If you did not implement the method, the default implementation runs getValues(). Running getValues() causes performance degradations. Implement a non-operational isValid() method to avoid potential performance degradations.

You must log in to answer this question.

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