This article provides a code pattern for querying Salesforce records using SOQL (Salesforce Object Query Language) via an Apex controller class and displaying those results in a Visualforce page or an Aura Lightning component. This is a common pattern used in custom Salesforce UI development when standard list views do not meet requirements.
Approach 1: Visualforce Page
Step 1 — Create an Apex Controller Class
Create an Apex class using the "with sharing" keyword to enforce sharing rules. Define a public List property of type Account with a getter and setter. In the class constructor, run a SOQL query that selects Name, AccountNumber, and CleanStatus from Account where CleanStatus equals "Pending". Store the returned records in the Records property.
Step 2 — Create the Visualforce Page
Create a Visualforce page and set the controller attribute to your Apex class name. Add an apex:pageBlock component with a title. Inside the pageBlock, add an apex:pageBlockTable component that iterates over the Records property using a loop variable. Add three apex:column components for Account Name, Account Number, and Clean Status, each using apex:outputText to render the corresponding field value.
Apex Class:
public with sharing class TestDisplayQueryList{
public List<Account> Records {get; set;}
public TestDisplayQueryList(){
Records =
[select Name, AccountNumber, CleanStatus from Account where CleanStatus='Pending'];
}
}
Visualforce Page:
<apex:page controller="TestDisplayQueryList">
<apex:pageBlock title="My Content">
<apex:pageBlockTable value="{!Records}" var="Record">
<apex:column >
<apex:facet name="header">Account Name</apex:facet>
<apex:outputText value="{!Record.Name}"/>
</apex:column>
<apex:column >
<apex:facet name="header">Account Number</apex:facet>
<apex:outputText value="{!Record.AccountNumber}"/>
</apex:column>
<apex:column >
<apex:facet name="header">Clean Status</apex:facet>
<apex:outputText value="{!Record.CleanStatus}"/>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
Approach 2: Aura Lightning Component
Step 1 — Create the Apex Controller with AuraEnabled Method
Create an Apex class with a static method named fetchAccount annotated with @AuraEnabled. This method returns a List of Account records. The SOQL query inside the method selects Name, AnnualRevenue, BillingState, and related Contact LastName from Account, with a LIMIT of 10 records.
Step 2 — Create the Aura Component and JavaScript Controller
Create an Aura component with an aura:handler for the init event that calls a doInit function in the component controller. Define an aura:attribute of type Account array called ListOfAccount to store the queried records. Add an aura:iteration in the component markup to iterate over the ListOfAccount attribute and render each Account's Name and its related Contacts.
Step 3 — Implement the doInit Function
In the Aura JavaScript controller, implement the doInit function. Use component.get to call the fetchAccount Apex method. In the success callback, use component.set to assign the returned account list to the ListOfAccount attribute. Enqueue the action using $A.enqueueAction.
Apex Class accWithContController.apxc
public class accWithContController {
@AuraEnabled
public static list < Account > fetchAccount() {
// query 10 records from account with their relevant contacts and return query.
List < Account > lstOfAcc = [select Name, AnnualRevenue, BillingState, (select LastName from contacts) from Account LIMIT 10];
return lstOfAcc;
}
}
Lightning Component
<aura:component controller="accWithContController">
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="ListOfAccount" type="Account[]" description="store accounts with there child contacts"/>
<ul>
<aura:iteration items="{!v.ListOfAccount}" var="acc">
<li type="dice">AccountName : {!acc.Name}</li>
<ul>
<aura:iteration items="{!acc.Contacts}" var="con" indexVar="index">
<li>contact {!index + 1} Name : {!con.LastName}</li>
</aura:iteration>
</ul>
<hr/>
</aura:iteration>
</ul>
</aura:component>
Controller Class
({
doInit: function(component, event, helper) {
//call apex class method
var action = component.get('c.fetchAccount');
action.setCallback(this, function(response) {
//store state of response
var state = response.getState();
if (state === "SUCCESS") {
//set response value in ListOfAccount attribute on component.
component.set('v.ListOfAccount', response.getReturnValue());
}
});
$A.enqueueAction(action);
},
})000386576

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.