1

I'm developing a custom lighting component, in which I have a table with 2 columns, each cell is composed by a strike_lookup

Everything works as expected until I have too many rows, thus too many lookups, thus too many queries in a single apex.

Now my problem is that I'm not doing too many queries myself, the strike_lookup when initialized does some queries, so that I reach the governor limits.

What I'm doing is the follows:

<aura:iteration items="{!v.data}" var="line">
            <tr>
                <td><c:strike_lookup
                                     object="Product2"
                                     searchField="ProductCode"
                                     value="{!line.product}"
                                     placeholder="Select a product"
                                     iconName="standard:custom"
                                     subtitleField="Name"
                                     order="ProductCode"
                                     limit="5"
                                     required="true"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     showRecentRecords="true"
                                     filter="RecordTypeId='01220000000YcPnAAK' AND Family!='Marketing' AND IsActive=True"/></td>
                <td><c:strike_lookup
                                     object="Scale_Quantity__c"
                                     searchField="Name"
                                     value = "{!line.scale}"
                                     placeholder="Select a scale"
                                     iconName="standard:custom"
                                     subtitleField="Scale_Code__c"
                                     order="Name"
                                     limit="5"
                                     required="true"
                                     loadingMessage="Loading..."
                                     showRecentRecords="true"
                                     errorMessage="Invalid input"/></td>

                <td><ui:inputCheckbox aura:id="checkbox" label="Delete? " value="{!line.del}"/></td>
            </tr>
        </aura:iteration>

Once initialized I fetch the data from the server and pass it to my js, which elaborates them and fill the v.data variable so that all my lines are created.

is there a way to bypass this situation?

I actually need all those records on the same page, in order to let my customers work as expected, so I'm not inclined in a "maximum-row-per-page" solution.

EDIT

 retrieveLines : function(cmp, helper) {
    //Using RecordID retrieve all line
    var action = cmp.get("c.retrieveLines");

    //Set the ID to pass
    action.setParams({
        //"id": component.get("v.recordId")
        "id": cmp.get("v.recordId")
    });

    action.setCallback(this, function(response) {
        //retrieve the lines present on the component
        var lines = cmp.get("v.data");

        //If those are null initialize the array
        if(lines == null){
            lines = new Array();
        }

        response.getReturnValue().forEach(function(line){

            //For each line insert the needed data
            lines.push(
                {
                    Id: line.Id,
                    product: line.Product__c,
                    scale: line.Scale_Quantity__c,
                    del: false
                }
            );
        });



        // now add the new array back to the attribute, so that it reflects on the component
        cmp.set("v.data", lines);  

    });
    $A.enqueueAction(action);
}
  • I don't think there's a viable alternative without modifying the strike code directly. The lookup is not really meant to be used this way. – sfdcfox Dec 27 '18 at 15:22
3

The Aura framework batches actions and so for your case the many queries initiated by the separate c:strike_lookup components are arriving at the server in a single transaction. Unfortunately, there is no way to configure this behavior directly to say make no more than 50 requests in one transaction.

However, you could create a custom table row component - everything between and including the <tr> and </tr> - and create that dynamically in JavaScript using $A.createComponents say 25 rows at a time in a Promise Chain. That would move each block of up to 25 rows into separate transactions and so avoid hitting the governor limit.

  • +1 Time of load is key here. They should be loaded in series setup most efficiently setting a lag timer. I was talking on a similar note here Lazy Loading for Lightning Components but I like the promise chain idea! – codeyinthecloud Dec 27 '18 at 16:05
  • I get what you are saying, and I can totally see how and why that works. Now my problem is that being in this Aura framework I'm not able to implement it. I'll post my code to retrieve those lines, are you able to put down a simple pseudo code to explain me how to do it? Thanks! – Zeno Trevisan Dec 28 '18 at 13:08
  • Could you hack the Strike controller to run action.setBackground(true); before it enqueues the action? There is no guarantee that backgrounded actions won't still get batched, but it has been reported that they do not get batched as severely. – Charles T Dec 28 '18 at 13:36
  • Tried hacking setBackground into the component, not working, but maybe because this components has other dependencies which also have query inside.. I'm trying now to implement the prosime chain custom components inception that keth suggested earlier. Will be back with that I got – Zeno Trevisan Jan 2 at 9:09
  • @ZenoTrevisan When you get that working, I suggest you post the code yourself as the answer and accept that answer - may help others in the future. – Keith C Jan 2 at 9:26
1

I got something working, it is not polished as I hoped it would be.

Anyway, in my first component (let's call it table component) having the table to be shown I have this code:

    <table class="slds-table slds-table_bordered">
    <thead>
        <th>Product</th>
        <th>Scale Quantity</th>
    </thead>
    <tbody>
        {! v.firstPanel}
    </tbody>
</table>

The second component is composed by the rows of the table and it is coded as follows:

 <aura:attribute name="lines" type="Object"/>
    <aura:iteration items="{!v.lines}" var="line">
            <tr>
                <td><c:strike_lookup
                                     object="Product2"
                                     searchField="ProductCode"
                                     placeholder="Select a product"
                                     iconName="standard:custom"
                                     label="product"
                                     value="{! line.product}"
                                     subtitleField="Name"
                                     order="ProductCode"
                                     limit="5"
                                     required="true"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     showRecentRecords="true"
                                    /></td>
                <td><c:strike_lookup
                                     object="Scale_Quantity__c"
                                     searchField="Name"
                                     placeholder="Select a scale"
                                     iconName="standard:custom"
                                     label="Scale"
                                     value="{! line.scale}"
                                     subtitleField="Scale_Code__c"
                                     order="Name"
                                     limit="5"
                                     required="true"
                                     loadingMessage="Loading..."
                                     showRecentRecords="true"
                                     errorMessage="Invalid input"/></td>

                <td><span><ui:inputCheckbox aura:id="checkbox" label="Delete? " value="{! line.del}"/></span></td>
            </tr>
        </aura:iteration>

Now from the first component (table), in the method in which I load all the data from the backend, I call pushRow, which is a recursive method used to create n rows at a time, in order to avoid governor limit.

 pushRow: function(lines, count, cmp, helper){ //count

    var cut = 5;

    $A.createComponent(
        "c:customLines",
        {
            "lines": lines.slice(count * cut,cut)
        },
        function(newCard, status, errorMessage){
            if (status === "SUCCESS") {
                var secondPanel = cmp.get("v.firstPanel");
                secondPanel.push(newCard);
                cmp.set("v.firstPanel", secondPanel);
                if(count * cut < lines.count){
                    helper.pushRow(lines, count+1, cmp, helper);
                } //to call again pushrows
            }
            else if (status === "INCOMPLETE") {
                console.log("No response from server or client is offline.")
            }
            else if (status === "ERROR") {
                    console.log("Error: " + errorMessage);
            }
        }
    );

},

Cut is the number of Rows I'm loading at each iteration.

I have the strong feeling that this is not the best possible solution, although it works. Is anyone able to tell me how I can make this recursion without blocking the UI when loading my record?

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.