Skip to main content

Many of us have probably run into a scenario where you need to load all records for a model, and have used the good ol’ loadAllRemainingRecords js.


Now there’s a declarative way to load all remaining records as well. There’s two parts to the solution


  • A model condition that only pulls in new values (Id not in (ThisModel)(Id)

  • An action sequence that loops and merge queries until ThisModel can't retrieve more rows

Here's the XML for an example that'll load all accounts in your org
<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" useviewportmeta="true" showheader="true">
<models>
<model id="Accounts" limit="5" query="true" createrowifnonefound="false" datasource="salesforce" sobject="Account">
<fields>
<field id="Id"/>
<field id="Name"/>
<field id="OwnerId"/>
<field id="Owner.Name"/>
</fields>
<conditions>
<condition type="modelmerge" value="" field="Id" operator="not in" model="Accounts" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="deactivate"/>
</conditions>
<actions/>
</model>
<model id="AccountsCount" query="true" createrowifnonefound="false" datasource="salesforce" sobject="Account">
<fields>
<field id="Id"/>
<field id="Name"/>
<field id="OwnerId"/>
<field id="Owner.Name"/>
</fields>
<conditions/>
<actions/>
<groupby method="simple"/>
</model>
</models>
<components>
<grid uniqueid="sk-3RwW-1192" columngutter="50px">
<divisions>
<division behavior="flex" minwidth="100px" ratio="1">
<components>
<pagetitle model="Accounts" uniqueid="sk-3Rx8-1694">
<maintitle>Only loading 5 accounts at a time cuz apex doesn't like you</maintitle>
<actions>
<action type="multi" label="Load All Remaining Records" uniqueid="sk-3RxB-1721">
<actions>
<action type="blockUI"/>
<action type="action-sequence" action-sequence-id="c4e8e325-a3fa-446e-9b82-d729f524307d"/>
</actions>
</action>
</actions>
</pagetitle>
<skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" hideheader="false" hidefooter="false" pagesize="10" alwaysresetpagination="false" createrecords="true" model="Accounts" buttonposition="" mode="read" allowcolumnreordering="true" responsive="true" uniqueid="sk-3Rue-284">
<fields>
<field id="Id" uniqueid="fi-3Rue-285"/>
<field id="Name" uniqueid="fi-3Rue-286"/>
<field id="OwnerId" uniqueid="fi-3Rue-287"/>
<field id="Owner.Name" uniqueid="fi-3Rue-288"/>
</fields>
<rowactions>
<action type="edit"/>
<action type="delete"/>
</rowactions>
<massactions usefirstitemasdefault="true">
<action type="massupdate"/>
<action type="massdelete"/>
</massactions>
<views>
<view type="standard"/>
</views>
<actions defaultlabel="Global Actions" defaulticon="sk-icon-magic" usefirstitemasdefault="true"/>
</skootable>
</components>
</division>
<division behavior="flex" verticalalign="top" minwidth="100px" ratio="1">
<components>
<pagetitle model="Accounts" uniqueid="sk-3Rx9-1701">
<maintitle>(Here's what you want as the end result)</maintitle>
<actions/>
</pagetitle>
<skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" hideheader="false" hidefooter="false" pagesize="10" alwaysresetpagination="false" createrecords="true" model="AccountsCount" buttonposition="" mode="read" allowcolumnreordering="true" responsive="true" uniqueid="sk-3RwO-1096">
<fields>
<field id="Id" uniqueid="fi-3RwO-1097"/>
<field id="Name" uniqueid="fi-3RwO-1098"/>
<field id="OwnerId" uniqueid="fi-3RwO-1099"/>
<field id="Owner.Name" uniqueid="fi-3RwO-1100"/>
</fields>
<rowactions>
<action type="edit"/>
<action type="delete"/>
</rowactions>
<massactions usefirstitemasdefault="true">
<action type="massupdate"/>
<action type="massdelete"/>
</massactions>
<views>
<view type="standard"/>
</views>
</skootable>
</components>
</division>
</divisions>
<styles>
<styleitem type="background" bgtype="none"/>
</styles>
</grid>
</components>
<resources>
<labels/>
<javascript/>
<css/>
<actionsequences uniqueid="sk-3RuX-221">
<actionsequence id="c4e8e325-a3fa-446e-9b82-d729f524307d" label="LoadAllReamingRecords_Accounts" type="reusable" uniqueid="sk-3RvX-694">
<description/>
<actions>
<action type="branch" whenfinished="stop">
<formula>{{$Model.Accounts.canRetrieveMoreRows}}==true</formula>
<iftrueactions>
<action type="requeryModel" model="Accounts" behavior="loadmore"/>
<action type="action-sequence" action-sequence-id="c4e8e325-a3fa-446e-9b82-d729f524307d"/>
</iftrueactions>
</action>
<action type="blockUI" message="I loaded all your accounts" timeout="3000"/>
</actions>
</actionsequence>
</actionsequences>
</resources>
<styles>
<styleitem type="background" bgtype="none"/>
</styles>
</skuidpage>

Thanks for posting this! Very helpful.


Also, the above example is for a dev org size sample. Here’s an example that’ll pull 100 at a time instead of 5…


<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" useviewportmeta="true" showheader="true">
<models>
<model id="Accounts" limit="100" query="true" createrowifnonefound="false" datasource="salesforce" sobject="Account">
<fields>
<field id="Id"/>
<field id="Name"/>
<field id="OwnerId"/>
<field id="Owner.Name"/>
</fields>
<conditions>
<condition type="modelmerge" value="" field="Id" operator="not in" model="Accounts" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="deactivate"/>
</conditions>
<actions/>
</model>
<model id="AccountsCount" query="true" createrowifnonefound="false" datasource="salesforce" sobject="Account" type="aggregate">
<fields>
<field id="Id" name="countId" function="COUNT"/>
</fields>
<conditions/>
<actions/>
<groupby method="simple"/>
</model>
</models>
<components>
<grid uniqueid="sk-3RwW-1192" columngutter="50px">
<divisions>
<division behavior="flex" minwidth="100px" ratio="1">
<components>
<pagetitle model="Accounts" uniqueid="sk-3Rx8-1694">
<maintitle>Only loading 100 accounts at a time cuz apex doesn't like you</maintitle>
<actions>
<action type="multi" label="Load All Remaining Records" uniqueid="sk-3RxB-1721">
<actions>
<action type="blockUI"/>
<action type="action-sequence" action-sequence-id="c4e8e325-a3fa-446e-9b82-d729f524307d"/>
</actions>
</action>
</actions>
</pagetitle>
<skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" hideheader="false" hidefooter="false" pagesize="10" alwaysresetpagination="false" createrecords="true" model="Accounts" buttonposition="" mode="read" allowcolumnreordering="true" responsive="true" uniqueid="sk-3Rue-284">
<fields>
<field id="Id" uniqueid="fi-3Rue-285"/>
<field id="Name" uniqueid="fi-3Rue-286"/>
<field id="OwnerId" uniqueid="fi-3Rue-287"/>
<field id="Owner.Name" uniqueid="fi-3Rue-288"/>
</fields>
<rowactions>
<action type="edit"/>
<action type="delete"/>
</rowactions>
<massactions usefirstitemasdefault="true">
<action type="massupdate"/>
<action type="massdelete"/>
</massactions>
<views>
<view type="standard"/>
</views>
<actions defaultlabel="Global Actions" defaulticon="sk-icon-magic" usefirstitemasdefault="true"/>
</skootable>
</components>
</division>
<division behavior="flex" verticalalign="top" minwidth="100px" ratio="1">
<components>
<pagetitle model="Accounts" uniqueid="sk-3Rx9-1701">
<maintitle>(Here's what you want as the end result)</maintitle>
<actions/>
</pagetitle>
<skootable showconditions="true" showsavecancel="false" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" hideheader="false" hidefooter="false" pagesize="10" alwaysresetpagination="false" createrecords="false" model="AccountsCount" buttonposition="" mode="readonly" allowcolumnreordering="true" responsive="true" uniqueid="sk-3gXD-360">
<fields>
<field id="Id" name="countId" uniqueid="fi-3gXD-361"/>
</fields>
<rowactions/>
<massactions usefirstitemasdefault="true"/>
<views>
<view type="standard"/>
</views>
</skootable>
</components>
</division>
</divisions>
<styles>
<styleitem type="background" bgtype="none"/>
</styles>
</grid>
</components>
<resources>
<labels/>
<javascript/>
<css/>
<actionsequences uniqueid="sk-3RuX-221">
<actionsequence id="c4e8e325-a3fa-446e-9b82-d729f524307d" label="LoadAllReamingRecords_Accounts" type="reusable" uniqueid="sk-3RvX-694">
<description/>
<actions>
<action type="branch" whenfinished="stop">
<formula>{{$Model.Accounts.canRetrieveMoreRows}}==true</formula>
<iftrueactions>
<action type="requeryModel" model="Accounts" behavior="loadmore"/>
<action type="action-sequence" action-sequence-id="c4e8e325-a3fa-446e-9b82-d729f524307d"/>
</iftrueactions>
</action>
<action type="blockUI" message="I loaded all your accounts" timeout="3000"/>
</actions>
</actionsequence>
</actionsequences>
</resources>
<styles>
<styleitem type="background" bgtype="none"/>
</styles>
</skuidpage>

Ah my bad on this misunderstanding. The declarative answer is in the post, but I realized the XML I posted was from a smaller org instead of one from a larger org. So it doesn’t have a limit on the basic query, which will cause the heap error when someone tries to load it. For whatever reason I couldn’t edit the main post anymore, so I just added a fixed version as a comment.


Nice!  Thanks for posting.