Work with Salesforce Data

In this blog post, we will explore different ways to work with Salesforce data in Lightning Web Components (LWC). Salesforce provides various tools and mechanisms to interact with data, ranging from base Lightning components built on Lightning Data Service (LDS) to the more flexible use of Apex. We will cover the following methods:

  1. Base Lightning Components Built on Lightning Data Service (LDS)
  2. LDS Wire Adapters
  3. Apex

1. Base Lightning Components Built on Lightning Data Service (LDS)

The easiest way to interact with Salesforce data in LWC is by using base Lightning components built on Lightning Data Service. These components, including `lightning-record-form`, `lightning-record-edit-form`, and `lightning-record-view-form`, offer simplicity and take care of field-level security and sharing automatically.

Features

  • lightning-record-form: Allows creating, editing, and viewing records. It provides read-only mode, layout types, and multicolumn layout.
  • lightning-record-view-form: Enables viewing records with options for read-only mode and custom layout for fields.
  • lightning-record-edit-form: Facilitates creating and editing records, along with custom layouts for fields.

Mode: edit, view, readonly
layout-type: full, compact


Drawback

  • Does not support all objects (Event and Task).

Benefits

  • Improves performance due to caching. If a record is updated, other components receive automatic updates.
  • Simplifies field-level security and sharing, showing users only the data they have access to.

 MIND IT !

Real-Time Scenario

Let's explore a real-time scenario using base Lightning components built on Lightning Data Service (LDS). In this scenario, we'll create a Lightning Web Component (LWC) to display the details of a specific Account using the `lightning-record-view-form` component.

Scenario: Displaying Account Details
Objective: Retrieve and display details of a specific Account using the lightning-record-view-form base Lightning component.


Implementation:

1. Create Apex Class to Fetch Data

// Apex class (AccountController)
public with sharing class AccountController {
    @AuraEnabled(cacheable=true)
    public static Account getAccountDetails(String accountId) {
        return [SELECT Id, Name, Industry, AnnualRevenue, Phone, Website FROM Account WHERE Id = :accountId LIMIT 1];
    }
}

2. Create Lightning Web Component (LWC)

// LWC component (AccountDetails)
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';

export default class AccountDetails extends LightningElement {
    @api recordId; // Account Id passed from the parent component or record page

    // Fetch data using wire adapter
    @wire(getRecord, { recordId: '$recordId', fields: ['Account.Name', 'Account.Industry', 'Account.AnnualRevenue', 'Account.Phone', 'Account.Website'] })
    account;

    // Getter to extract data from wire result
    get accountDetails() {
        return this.account.data ? this.account.data.fields : {};
    }
}

3. Use lightning-record-view-form in LWC HTML




Explanation:

  • The `AccountController` Apex class provides a method (`getAccountDetails`) to retrieve details of a specific Account based on the provided Account Id.
  • In the Lightning Web Component (`AccountDetails`), the `@wire` decorator is used to call the `getRecord` wire adapter, which dynamically fetches data for the specified Account fields.
  • The HTML template uses the `lightning-record-view-form` component to display the details of the Account.
  • Conditional rendering is used to display a message if no Account details are found.

Output:


If no Account details are found


  • When the `AccountDetails` component is rendered with a valid `recordId` (Account Id), it dynamically fetches and displays the details of the specified Account, including fields like Name, Industry, Annual Revenue, Phone, and Website.
  • If no Account details are found, a message stating "No Account details found" is displayed.

This scenario demonstrates how base Lightning components like `lightning-record-view-form` can simplify the process of fetching and displaying Salesforce data in a Lightning Web Component.


2. LDS Wire Adapters

LDS Wire Adapters provide a more flexible approach to work with Lightning Data Service. Using `@wire`, you can specify the `getRecord` function to apply business logic on data and create more customizable forms.

Usage

  • If you need more flexibility, use a Lightning Data Service wire adapter directly. Each wire adapter provides different data and metadata.
  • Apply business logic on data or create customizable forms using `@wire` to specify `getRecord`.
  • Retrieve raw record information like picklists, recordInfo, and ObjectInfo.
  • Reactive behavior – data updates are immediately reflected.
    `@wire` is reactive, means once data is available it immidiately update it.
  • The LDS wire adapters are built on User Interface API resources and live in the `lightning/ui*Api` modules.
  • To make property as reactive, we prefix with ‘$’ eg:- `$propertyName`.

Drawback

  • Independent transactions for each operation. To work with multiple records in a single transaction, use Apex or GraphQL.

Various Wire Adapters lightning/ui*Api

  • lightning/uiRecordApi
  • lightning/uiObjectInfoApi
  • lightning/uiListsApi
  • lightning/uiAppApi
  • lightning/uiRelatedListApi

 MIND IT !

Real-Time Scenario

Let's explore a real-time scenario of working with Salesforce Data in Lightning Web Components (LWC). In this scenario, we want to create an LWC that displays information about the five most recently modified Opportunities. We will leverage Lightning Data Service (LDS) wire adapters to achieve this, ensuring efficient and secure data retrieval.

Scenario: Displaying Recently Modified Opportunities
Objective: Retrieve and display information about the five most recently modified Opportunities using LDS Wire Adapters.

Implementation:

1. Create Apex Class to Fetch Data

// Apex class (OpportunityController)
public with sharing class OpportunityController {
    @AuraEnabled(cacheable=true)
    public static List<Opportunity> getRecentlyModifiedOpportunities() {
        Date thirtyDaysAgo = Date.today().addDays(-30);
        
        return [SELECT Id, Name, StageName, CloseDate 
                FROM Opportunity 
                WHERE LastModifiedDate >= :thirtyDaysAgo 
                ORDER BY LastModifiedDate DESC LIMIT 5];
    }
}

2. Create Lightning Web Component (LWC) Using LDS Wire Adapters

// LWC component (RecentlyModifiedOpportunitiesLDS)
import { LightningElement, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
import getRecentlyModifiedOpportunities from '@salesforce/apex/OpportunityController.getRecentlyModifiedOpportunities';

const FIELDS = ['Opportunity.Name', 'Opportunity.StageName', 'Opportunity.CloseDate'];

export default class RecentlyModifiedOpportunitiesLDS extends LightningElement {
    @wire(getRecentlyModifiedOpportunities)
    opportunities;

    // Alternatively, you can use the following wire adapter for individual record fields:
    // @wire(getRecord, { recordId: '$opportunityId', fields: FIELDS })
    // opportunity;

    // Optional: If you want to display individual fields using getRecord wire adapter
    // get opportunityId() {
    //     return this.opportunities.data ? this.opportunities.data[0].Id : null;
    // }

    // Optional: If you want to display individual fields using getRecord wire adapter
    // get opportunityName() {
    //     return this.opportunity.data ? this.opportunity.data.fields.Name.value : 'N/A';
    // }
}

3. Use the Lightning Web Component in HTML Template




Explanation:

  • The `OpportunityController` Apex class provides a method (`getRecentlyModifiedOpportunities) to retrieve details of the five most recently modified Opportunities in the last 30 days.
  • The Lightning Web Component (`RecentlyModifiedOpportunitiesLDS`) uses the `@wire` decorator to call the `getRecentlyModifiedOpportunities` wire adapter, which dynamically fetches the Opportunities.
  • The HTML template displays the recently modified Opportunities, including their Name, Stage, and Close Date. Conditional rendering is used to handle the scenario where no opportunities are found.

Output:


  • When the `RecentlyModifiedOpportunitiesLDS` component is rendered, it dynamically fetches and displays the details of the five most recently modified Opportunities, including their Name, Stage, and Close Date.
  • If no recently modified opportunities are found, a message stating "No recently modified opportunities found" is displayed.

This real-time scenario demonstrates the seamless integration of Salesforce data into a Lightning Web Component using Lightning Data Service wire adapters, providing a user-friendly and performance-optimized solution.


3. Apex

When LDS Wire Adapters lack the required flexibility, Apex can be employed. It's ideal for performing operations on Task and Event objects, implementing record filtration, and executing transactional operations.

 MIND IT !

  1. Use when you wanna perform operation on Task and Event objects.
  2. Use when you need filtration of records eg. amount >= 100.
  3. Use to perform transactional operation, either full or partial transactional.

Usage

  • Utilize `@wire` for simplicity.
  • Adopt an imperative approach.
  • With help of `Async` and `await` (more cleaner to write code)

When to use Imperative Approach

  1. To control when the method invocation occurs (for example, in response to clicking a button), call the method imperatively.
  2. To call a method that isn’t annotated with cacheable=true, which includes any method that inserts, updates, or deletes data.

When to use Async and Await

  1. When we need to call multiple methods from apex controller class on single call.
  2. We can make apex method chaining.
  3. `async` function always return promises.
  4. In await function, you’re essentially telling your code to stop and wait for the result of the asynchronous function to complete before going any further.
  5. `await` pause until the async function is done.

For More details about the Work with Apex Method in LWC

Conclusion

Working with Salesforce data in Lightning Web Components offers a range of options to suit different needs. Whether you prefer the simplicity of base Lightning components, the flexibility of LDS Wire Adapters, or the power of Apex, Salesforce provides a comprehensive set of tools for developers. Understanding the strengths and trade-offs of each approach helps in making informed decisions when building robust and efficient LWC applications.


 MIND IT !

Practice on Various Wire Adapters lightning/ui*Api

let's explore practical scenarios for working with various wire adapters in the lightning/ui*Api module within Lightning Web Components (LWC). We'll cover a range of use cases to help you gain hands-on experience and proficiency with these powerful tools.


1. `lightning/uiRecordApi`

Scenario: Displaying Contact Details
Objective: Retrieve and display details of a specific Contact using `uiRecordApi`.


Implementation:

1. Create Apex Class to Fetch Data

// Apex class (ContactController)
public with sharing class ContactController {
    @AuraEnabled(cacheable=true)
    public static Contact getContactDetails(String contactId) {
        return [SELECT Id, Name, Email, Phone FROM Contact WHERE Id = :contactId LIMIT 1];
    }
}

2. Create Lightning Web Component (LWC) Using `uiRecordApi`

// LWC component (ContactDetails)
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';

export default class ContactDetails extends LightningElement {
    @api recordId; // Contact Id passed from the parent component or record page

    // Fetch data using uiRecordApi wire adapter
    @wire(getRecord, { recordId: '$recordId', fields: ['Contact.Name', 'Contact.Email', 'Contact.Phone'] })
    contact;

    // Getter to extract data from wire result
    get contactDetails() {
        return this.contact.data ? this.contact.data.fields : {};
    }
}

3. Use the Lightning Web Component in HTML Template




Explanation:

  • The `ContactController` Apex class provides a method (`getContactDetails`) to retrieve details of a specific Contact based on the provided Contact Id.
  • In the Lightning Web Component (`ContactDetails`), the `@wire` decorator is used to call the `getRecord` wire adapter, which dynamically fetches data for the specified Contact fields.
  • The HTML template displays the details of the Contact, including Name, Email, and Phone.
  • Conditional rendering is used to display a message if no Contact details are found.

Output:


  • When the `ContactDetails` component is rendered with a valid `recordId` (Contact Id), it dynamically fetches and displays the details of the specified Contact, including Name, Email, and Phone.
  • If no Contact details are found, a message stating "No Contact details found" is displayed.

This scenario illustrates the usage of uiRecordApi in Lightning Web Components to efficiently retrieve and display Salesforce record details.


2. `lightning/uiListsApi`

Scenario: Displaying Opportunities in a Custom List
Objective: Retrieve and display a custom list of Opportunities using`uiListsApi`.


The `lightning/uiListsApi` module in Salesforce Lightning Web Components (LWC) is used to retrieve and display lists of records, including standard and custom lists. The following scenario demonstrates how to use `uiListsApi` to display a custom list of Opportunities in an LWC.

Implementation:

1. Create a Lightning Web Component:

Create a new Lightning Web Component named `OpportunityList`.





2. JavaScript File:

Implement the logic to retrieve Opportunities using `uiListsApi` in the JavaScript file.

// OpportunityList.js
import { LightningElement, wire } from 'lwc';
import { getListUi } from 'lightning/uiListsApi';

const COLUMNS = [
    { label: 'Opportunity Name', fieldName: 'Name', type: 'text' },
    { label: 'Stage', fieldName: 'StageName', type: 'text' },
    { label: 'Amount', fieldName: 'Amount', type: 'currency', typeAttributes: { currencyCode: 'USD' } },
    // Add more columns as needed
];

export default class OpportunityList extends LightningElement {
    columns = COLUMNS;

    @wire(getListUi, { objectApiName: 'Opportunity', listViewApiName: 'Your_Custom_List_API_Name' })
    opportunities;

    // You need to replace 'Your_Custom_List_API_Name' with the API name of your custom list view.
}

Explanation:

  • The HTML template displays a Lightning card containing a Lightning datatable to showcase the Opportunities.
  • The JavaScript file imports `getListUi` from `lightning/uiListsApi` to fetch the custom list of Opportunities.
  • `COLUMNS` defines the columns to be displayed in the datatable.
  • The `@wire` decorator calls the `getListUi` function, providing the object API name (`Opportunity`) and the API name of the custom list view (`Your_Custom_List_API_Name`).
  • If the data is available, it populates the datatable. If there's a loading state, it shows a spinner. In case of an error, it displays an error message.

Output:

  • When the component is added to a Lightning page, it will fetch and display the Opportunities based on the criteria defined in the custom list view.
  • The datatable will show Opportunity names, stages, amounts, and any other columns defined in the `COLUMNS` array.

Ensure that you replace 'Your_Custom_List_API_Name' with the actual API name of your custom list view. Additionally, customize the columns in the `COLUMNS` array based on the fields you want to display.


3. `lightning/uiAppApi`

Scenario: Dynamic App Navigation
Objective: Dynamically navigate to a custom app page using`uiAppApi`.


The `lightning/uiAppApi module in Salesforce Lightning Web Components (LWC) provides the ability to dynamically navigate to a custom app page. This scenario demonstrates how to use `uiAppApi` for dynamic app navigation.

Implementation:

1. Create a Lightning Web Component:

Create a new Lightning Web Component named `DynamicAppNavigation`.




2. JavaScript File:

  • Implement the logic to dynamically navigate to a custom app page using `uiAppApi` in the JavaScript file.
  • Ensure that you replace 'Custom_App_Name__c' with the API name of your custom app.

Here in the below example :

  • Lightning App builder : LWC SCENARIO
  • API Name : LWC_SCENARIO (Custom_App_Name__c)

// DynamicAppNavigation.js
import { LightningElement, api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import { encodeDefaultFieldValues } from 'lightning/pageReferenceUtils';

export default class DynamicAppNavigation extends NavigationMixin(LightningElement) {
    @api customObjectValue = 'SampleValue';

    navigateToCustomPage() {
        // Construct a page reference with custom app page details
        const pageReference = {
            type: 'standard__app',
            attributes: {
                //appTarget: 'Custom_App_Name__c' // Replace with your custom app's API name
                appTarget: 'LWC_SCENARIO' // Replace with your custom app's API name
            },
            state: {
                c__customObjectValue: this.customObjectValue
            }
        };

        // Navigate to the custom app page
        this[NavigationMixin.Navigate](pageReference);
    }
}

Explanation:

  • The HTML template displays a Lightning card containing a button that, when clicked, triggers the dynamic app navigation.
  • The JavaScript file imports `NavigationMixin` from `lightning/navigation` and `encodeDefaultFieldValues` from `lightning/pageReferenceUtils`.
  • The `DynamicAppNavigation` component extends `NavigationMixin(LightningElement)` to enable navigation.
  • The `navigateToCustomPage` method constructs a page reference for the custom app page. It specifies the app target and includes any necessary state parameters (in this case, `c__customObjectValue`).
  • The `this[NavigationMixin.Navigate](pageReference)` line performs the actual navigation.

Output:

Click on 'Navigate to Custom Page' button.


After Click on 'Navigate to Custom Page' button. it dynamically navigates to the specified custom app page 'LWC SCENARIO'.


  • When you add the `DynamicAppNavigation` Lightning Web Component to a Lightning page and click the "Navigate to Custom Page" button, it dynamically navigates to the specified custom app page (`Custom_App_Name__c`) with the provided state parameter (`c__customObjectValue`).
  • Ensure that you replace 'Custom_App_Name__c' with the API name of your custom app.

This scenario demonstrates how to use uiAppApi for dynamic app navigation in a Lightning Web Component.


“Stay tuned for more exciting LWC topics, and keep exploring the world of Lightning Web Components to become a Salesforce development pro.”

Happy coding with LWC!

Share This Post:

About The Author

Hey, my name is Saurabh Samir and I am Salesforce Developer. I have been helping to elevate your Lightning Web Components (LWC) Knowledge. Do comment below if you have any questions or feedback's.