How to Build a Custom Object LWC Data Table in Salesforce

In Salesforce, we can create a data table in Lightning Web Components using the standard lightning-datatable component. However, to create a custom table for a custom object, we need to define the columns and types according to the custom fields within the custom object.

In this Salesforce tutorial, we will learn how to build a custom LWC data table for a custom object in Salesforce.

Custom Object LWC Datatable in Salesforce

We can follow the approaches to create a custom object LWC data table in Salesforce.

  • Custom object LWC data table with client-side rendering
  • Custom object LWC data table with server-side rendering

In the examples below, we will cover both methods of creating a custom object LWC data table in Salesforce.

Create Custom Object LWC Datatable With Client Side Rendering

To create a custom LWC data table via client-side rendering, we fetch the object data using an Apex class. Therefore, we will also define a controller class to fetch the custom object record.

Follow the steps below to create an LWC data table for a custom object via client-side rendering.

In the example below, I will use the custom object from my org, Survey_Responses__c.

  1. First, we will create a controller class to fetch records from the custom object Survey Responses dynamically.
public with sharing class SurveyController {
    @AuraEnabled(cacheable=true)
    public static List<Survey_Response__c> getSurveyResponses() {
        return [SELECT Id, Name, Comment__c, CurrencyIsoCode, 
                Email__c, Survey_submitted__c
                FROM Survey_Response__c
                WITH SECURITY_ENFORCED
                ORDER BY CreatedDate DESC];
    }
}

In this controller class, I have retrieved the custom and standard fields of the custom object; the values annotated with “__c” are the custom fields. We can refer to the object API name from the Fields and Relationships setup.

2. After this, create the LWC component and enter the code below in the HTML file.

We have defined the table heading in the card title and used the lightning-datatable attribute to render the data in a tabular format.

    <template>
        <lightning-card title="Survey Responses" icon-name="custom:custom63">
            <div class="slds-m-around_medium">
                <lightning-datatable
                    key-field="Id"
                    data={surveyData}
                    columns={columns}
                    hide-checkbox-column="true">
                </lightning-datatable>
            </div>
        </lightning-card>
    </template>

    The data attribute maps and renders the returned data, and the columns attribute renders the column in a data table that we will define in the JS file’s columns array.

    3. Now, enter the code below in the JS file to define the columns and the logic to handle errors caused by invalid data.

    In the column array, define the label, field name, and field type. Ensure that you enter the correct data type; for example, if a field is a checkbox field, its data type will be ‘boolean’. The fieldName can be checked by referring to the Field API name in the object settings.

    If the data is fetched, then data.map will assign the field values to the table columns.

    import { LightningElement, wire, track } from 'lwc';
    import { getRecord } from 'lightning/uiRecordApi';
    import getSurveyResponses from '@salesforce/apex/SurveyResponseController.getSurveyResponses';
    
    const COLUMNS = [
        { label: 'Name', fieldName: 'Name', type: 'text' },
        { label: 'Comment', fieldName: 'Comment__c', type: 'text' },
        { label: 'Email', fieldName: 'Email__c', type: 'email' },
        { label: 'Survey Submitted', fieldName: 'Survey_submitted__c', type: 'boolean' }
    ];
    
    export default class SurveyResponseDataTable extends LightningElement {
        @track surveyData = [];
        @track columns = COLUMNS;
        @track error;
    
        @wire(getSurveyResponses)
        wiredSurveyResponses({ error, data }) {
            if (data) {
                this.surveyData = data.map(record => {
                    return {
                        ...record,
                        CreatedByName: record.CreatedBy ? record.CreatedBy.Name : ''
                    };
                });
                this.error = undefined;
            } else if (error) {
                this.error = error;
                this.surveyData = [];
                console.error('Error retrieving survey responses:', error);
            }
        }
    }

    4. To make the component visible on the lightning page, enter the code below in the meta.xml file.

    <isExposed>true</isExposed>
        <targets>
            <target>lightning__AppPage</target>
            <target>lightning__RecordPage</target>
            <target>lightning__HomePage</target>
        </targets>

    5. Go to the Lightning page, where you have to deploy this LWC component and click on the settings, then select Edit page.

    6. Now, the app page will be opened in the Lightning App Builder, and here search for the LWC component, then drag it to the page canvas. At last, click Save to apply the changes.

    Create a Lightning Data table for custom object in Salesforce

    Now, the Lightning data table will display the columns defined in the Columns array and the values of those column fields fetched from the controller class.

    Salesforce LWC data table for custom object

    This way, we can create a Lightning data table in LWC for a custom Salesforce object by following the above steps.

    Create Custom Object LWC Datatable via Server Side Rendering

    To create a lightning datatable for a custom object, we have another method of rendering data in the LWC data table via server-side rendering.

    This method defines the logic for rendering the data directly in the HTML file from the controller method.

    Follow the steps below to create a Lightning data table for a custom object with server-side rendering.

    1. In the server-side rendering, instead of fetching data on the client side using @wire in LWC, we will pre-fetch it in the Apex controller, which will return data in a JSON string.

    public with sharing class SurveyController {
        @AuraEnabled(cacheable=true)
        public static String getSurveyResponses() {
            List<Survey_Response__c> responses = [SELECT Id, Name, Comment__c,                                                CurrencyIsoCode, 
                                                  Email__c, Survey_submitted__c,DOB__c
                                                  FROM Survey_Response__c
                                                  WITH SECURITY_ENFORCED
                                                  ORDER BY CreatedDate DESC];
            return JSON.serialize(responses);
        }
    }

    This will convert the records into JSON format, allowing them to be embedded in the HTML template of the LWC component.

    2. Enter the code below in the HTML template so the data can be read directly from the HTML template.

    <template>
        <template if:true={surveyData}>
            <lightning-card title="Survey Responses" icon-name="custom:custom63">
                <div class="slds-m-around_medium">
                    <lightning-datatable
                        key-field="Id"
                        data={surveyData}
                        columns={columns}
                        hide-checkbox-column="true">
                    </lightning-datatable>
                </div>
            </lightning-card>
        </template>
        <template if:true={error}>
            <p class="slds-text-color_error">Error loading data: {error}</p>
        </template>
    </template>

    3. Enter the code below in the JS file to process the data at load time instead of fetching it separately.

    import { LightningElement, track } from 'lwc';
    import getSurveyResponses from '@salesforce/apex/SurveyController.getSurveyResponses';
    
    const COLUMNS = [
        { label: 'Name', fieldName: 'Name', type: 'text' },
        { label: 'Comment', fieldName: 'Comment__c', type: 'text' },
        { label: 'Email', fieldName: 'Email__c', type: 'email' },
        { label: 'Date of Birth', fieldName: 'DOB__c', type: 'date' },
        { label: 'Survey Submitted', fieldName: 'Survey_submitted__c', type: 'boolean' }
    ];
    
    export default class SurveyResponseDataTable extends LightningElement {
        @track surveyData = [];
        @track columns = COLUMNS;
        @track error;
    
        connectedCallback() {
            getSurveyResponses()
                .then(data => {
                    this.surveyData = JSON.parse(data);
                    this.error = undefined;
                })
                .catch(error => {
                    this.error = error;
                    this.surveyData = [];
                    console.error('Error retrieving survey responses:', error);
                });
        }
    }

    In this, we have used connectedCallback() instead of the @wire method to ensure data is fetched at render time. It also deserialises JSON data with JSON.parse(data), which was preloaded from the server.

    4. At last, enter the code below in the meta.xml file to make the LWC component available for the Lightning page.

    <isExposed>true</isExposed>
        <targets>
            <target>lightning__RecordPage</target>
            <target>lightning__AppPage</target>
            <target>lightning__HomePage</target>
        </targets>

    5. Now, deploy the Lightning web component to the Lightning page. The data will then be displayed on the LWC data table, and this data is rendered directly in the HTML from the controller class.

    Custom object LWC data table with server side rendering

    This approach reduces client-server requests by fetching data once at render time, improving performance by preloading data instead of making separate Apex calls. This approach is also optimized for large datasets, as only essential data is passed.

    Here, you will also notice that while refreshing the page or updating data, the server-side rendering will return data faster than client-side rendering because in client-side rendering, the browser has to fetch and execute all the necessary JavaScript logic before rendering the data.

    Conclusion

    In this Salesforce tutorial, we learned how to create a Lightning Data Table for a custom object, Survey_Responses__c, using the Lightning Datatable extension. In the above, we created a data table using both client-side and server-side rendering.

    In the client-side rendering, we used the @wire method to map the data in the JS file and then rendered it in HTML. In the server-side rendering, we used the connectedCallback() method to render the data directly in HTML.

    You may also like to read:

    Agentforce in Salesforce

    DOWNLOAD FREE AGENTFORCE EBOOK

    Start with AgentForce in Salesforce. Create your first agent and deploy to your Salesforce Org.

    Salesforce flows complete guide

    FREE SALESFORCE FLOW EBOOK

    Learn how to work with flows in Salesforce with 5 different real time examples.