top of page
Writer's pictureN. Mehra

FETCHING AND DISPLAYING ACCOUNT AND CONTACT DATA IN A LIGHTNING WEB COMPONENT

Updated: Oct 17, 2023



In the world of Salesforce development, Lightning Web Components (LWC) have gained popularity for building interactive and responsive user interfaces. LWC provides a modern and efficient way to develop components that can be seamlessly integrated into the Salesforce ecosystem. In this blog post, we'll dissect a specific LWC code snippet that displays account and contact data in a tabular format and explores the concept of modals or popup boxes for further interaction.


HTML - AccountsDataToDisplay.html


<template>
    <lightning-cardclass="card">
        <divclass="container">
            <tableborder="solid">
                <thead>
                    <th>{Id}</th>
                    <th>{Name}</th>
                </thead>
                <tbody>
                    <templatefor:each={accounts}for:item="acc">
                        <trkey={acc.account.Id}>
                             <td>{acc.account.Id}</td>
                             <td>
                                 <div onclick={openModal}><aid={acc.account.Id}value={acc.account.Id}>{acc.account.Name}</a></div>
                             </td>
                        </tr>
                    </template>
                </tbody>
                <templateif:true={isModalOpen}>
                    <!--   Modal/Popup Box LWC starts here -->
                    <sectionrole="dialog"tabindex="-1"aria-labelledby="modal-heading-01"aria-modal="true"
                        aria-describedby="modal-content-id-1"class="slds-modal   slds-fade-in-open">
                        <divclass="slds-modal__container">
                             <!-- Modal/Popup Box LWC header here -->
                             <headerclass="slds-modal__header">
                                 <button class="slds-button   slds-button_icon slds-modal__close slds-button_icon-inverse"
                                    title="Close"onclick={closeModal}>
                                    <lightning-iconicon-name="utility:close"alternative-text="close"variant="inverse"
                                        size="small"></lightning-icon>
                                    <spanclass="slds-assistive-text">Close</span>
                                 </button>
                                 <h2 id="modal-heading-01"class="slds-text-heading_medium   slds-hyphenate">{accountName}</h2>
                             </header>
                            <!-- Modal/Popup Box   LWC body starts here -->
                             <div class="slds-modal__content   slds-p-around_medium" id="modal-content-id-1">
                                 <template if:true={checkTrue}>
                                    <ulstyle=" list-style-type:   circle;padding-left:7%">
                                    <tableclass="modalTable">
                                        <tbodystyle="text-align:center">
                                         <templatefor:each={contactListShown}for:item="con">
                                            <trkey={con.key}>
                                                 <td> <b>{con.Value}</b></td>
                                                 <td class="viewBtn">
                                                     <lightning-buttonvalue={con.key} label="View   Contact" onclick={navigateToViewContactPage}></lightning-button>
                                                 </td>
                                            </tr>
                                        </template>
                                    </tbody>
                                    </table>
                                    </ul>

                                 </template>
                                 <template if:false={checkTrue}>
                                    <p>{NoContacts}</p>
                                 </template>
                             </div>
                        </div>
                    </section>
                    <divclass="slds-backdrop   slds-backdrop_open"></div>
                </template>
            </table>
        </div>
    </lightning-card>
</template>

Displaying Account Data

The initial part of the code focuses on rendering the account data in a tabular format. It uses the lightning-card component to create a visually appealing container. Inside the card, a table structure is used to organize the data. The thead element represents the table header, defining two columns: "Id" and "Name."

The tbody element contains a template directive, which leverages iteration using the for:each attribute. This iterates over an array of accounts and assigns each item to the acc variable. For every account, a tr (table row) element is generated with a unique key attribute.

Inside each row, the account's Id and Name are displayed using td (table data) elements. The style attribute is used to center-align the Id value.


Modal/Popup Box

The next part of the code introduces the concept of a modal or popup box, which provides additional information upon user interaction. The modal is conditionally rendered based on the value of the isModalOpen property.

The modal is implemented using the section element with the role of "dialog." It is visually highlighted using the CSS classes slds-modal and slds-fade-in-open. The aria-* attributes ensure accessibility by providing descriptive information to assistive technologies.

Within the modal, a header section (slds-modal__header) displays the account name as the title. A close button with an associated icon (lightning-icon) is also provided for dismissing the modal. The content of the modal is enclosed within the slds-modal__content class.


Displaying Contact Data in Modal

The modal's content varies based on a condition evaluated by the checkTrue property. If the condition is met, a list of contacts is displayed in a tabular format. The contacts are iterated over using the for:each directive, similar to the account rendering. Each contact is represented by a tr element with a unique key.

The contact's value is displayed using the td element, and a button labeled "View Contact" is rendered using the lightning-button component. Clicking this button triggers the navigateToViewContactPage function.

In case the checkTrue condition is not met, a simple message stating "No Contacts" is displayed within the modal.


JS - AccountsDataToDisplay.js

import { LightningElement,   wire,track } from'lwc';
import getAccounts from'@salesforce/apex/AccountController.getAccountList';
import Name from'@salesforce/label/c.Name';
import Id from'@salesforce/label/c.Id';
import NoContacts from'@salesforce/label/c.No_Contacts';
import {ShowToastEvent}   from 'lightning/platformShowToastEvent';
import { NavigationMixin   } from 'lightning/navigation';

export default classAccountContactsDisplay extendsNavigationMixin(LightningElement)   {
    accounts;
    AccountMap= [];
    @trackaccountName;
    accountList= [];
    @trackcheckTrue = false;
    @trackcontactListShown;
    @trackisModalOpen = false;
    Id= Id;
    Name= Name;
    NoContacts= NoContacts;

    @wire(getAccounts)   getAccount({data,error}){
        if(data){
            this.accounts=data;
            for(leti = 0; i <data.length ; i++){
                letcontacts = data[i]["account"]["Contacts"];
                letcontactList = [];
                if(contacts){
                    for(letj = 0; j <contacts.length;   j++){
                        letName = contacts[j]["FirstName"]   != null? contacts[j]["FirstName"]   + contacts[j]["LastName"]:contacts[j]["LastName"];
                        contactList.push({"key":contacts[j]["Id"],"Value":Name});
                    }
                }
                this.AccountMap.push({"key":data[i]["account"]["Id"]+","+data[i]["account"]["Name"],"value":JSON.stringify(contactList)});
            }
        }
        elseif(error){
            this.ShowToastEventError(error);
        }
    };

     //   Navigate to View Contact Page
     navigateToViewContactPage(event)   {
        letkey = event.target.value;
        console.log('key>>>'+key);
        this[NavigationMixin.Navigate]({
            type:'standard__recordPage',
            attributes:   {
                "recordId":key,
                "objectApiName":"Contact",
                "actionName":"view",
            },
        });
    }

    handleClick(event){
       letvalue = event.target.id;
       letId = value.substring(0,18);
       this.AccountMap.forEach(element=> {
            letkey = JSON.stringify(element["key"]);
            letmatchID = key.split(",")[0];
            if(matchID.match(Id)){
                letname =  key.split(",")[1];
                letlen = name.length;
                this.accountName= name.substring(0,len-1);
                letcontacts = element["value"];
                console.log("contact"+contacts);
                if(contacts.length> 2){
                    for(leti = 0; i <contacts.length   ; i++){
                        this.contactListShown= JSON.parse(contacts);
                    }
                    this.checkTrue= true;
                }
                else{
                    this.checkTrue= false;
                }
            }
        });
    }

    ShowToastEventError(error){
        constevent = newShowToastEvent({
                title:"Error",
                message:error,
                variant:"Error",
        });
        this.dispatchEvent(event);
    }

    openModal(event)   {
        //   to open modal set isModalOpen tarck value as true
        this.isModalOpen= true;
        this.handleClick(event);

    }

    closeModal()   {
        //   to close modal set isModalOpen tarck value as false
        this.isModalOpen= false;
    }

    submitDetails()   {
        //   to close modal set isModalOpen tarck value as false
        //Add   your code to call apex method or do some processing
        this.isModalOpen= false;
    }
}

Importing Dependencies and Class Definition


The component imports necessary modules, including the LightningElement, wire, track, ShowToastEvent, and NavigationMixin, from the LWC and Lightning platforms.

The component class AccountsDataToDisplay extends NavigationMixin(LightningElement), allowing the component to utilize the navigation mixin to navigate to the contact record page.


Class Properties

The component defines various properties using the @track decorator. These properties include accounts, AccountMap, accountName, accountList, checkTrue, contactListShown, and isModalOpen. These properties are used to store and track data within the component.


Wire Service - Retrieving Account Data

The @wire decorator is used to call the getAccounts Apex method, which retrieves a list of accounts. The wire service automatically handles the retrieval of data from the server and updates the accounts property when the data is available. If an error occurs, the showToastEventError method is called to display an error toast.


Apex Class-


AccountController.cls

public classAccountController{  
    @AuraEnabled(cacheable=True)//Get Account Records
    public static List<AccountWrapper> getAccountList(){
return AccountProcessor.getdomain();
    }
}

AccountWrapper.cls

public   class AccountWrapper {
    @AuraEnabled
    public Account account;
    public AccountWrapper(Account   account) {
        this.account = account;
    }
   }

AccountProcessor.cls

public   class AccountProcessor {
    public static List<AccountWrapper> getdomain() {
         List<AccountWrapper> processedData = new List<AccountWrapper>();
        for(Account acc : AccountDomain.getAccounts()) {
            processedData.add(new   AccountWrapper(acc));
        }
        return processedData;
    }
   }

AccountDomain.cls

public   without sharing class AccountDomain {
    @AuraEnabled(Cacheable= True)
    public static List<Account> getAccounts() {
        return [
            Select
                Id,
                Name,
                AccountNumber,
                Phone,
                Industry,
                (
                    SELECT
                        Id,
                        FirstName,
                        LastName
                    From
                        Contacts
                )
            FROM
                Account
            LIMIT
                200
        ];
    }
   }


Processing Account and Contact Data

Inside the wire method, the retrieved account data is processed to create a mapping between account IDs and contact details. For each account, the associated contacts are extracted and stored in a contactList. The AccountMap is then populated with the account ID and name as the key and the contactList as the value.


Handling User Interaction

The handleClick method is triggered when the user clicks on an account's name within the table. It retrieves the account's ID and uses it to find the associated contactList in the AccountMap. The accountName property is updated with the account's name, and the checkTrue property is set based on whether there are contacts available. If there are contacts, they are assigned to the contactListShown property.

The navigateToViewContactPage method is called when the user clicks the "View Contact" button in the modal. It extracts the contact's ID from the event and uses the navigation mixin to navigate to the contact's record page.


Modal Functionality

The openModal method is triggered when the user clicks on the account name, and it opens the modal by setting the isModalOpen property to true. It also calls the handleClick method to populate the modal with the relevant data.

The closeModal method is called when the user clicks the close button in the modal, and it closes the modal by setting the isModalOpen property to false.

The submitDetails method is currently a placeholder for any additional functionality or processing that you may want to include when submitting the modal details.


Displaying Toast Messages

The showToastEventError method is responsible for displaying an error toast when an error occurs during the retrieval of account data. It creates a new ShowToastEvent instance with the appropriate parameters and dispatches the event to display the toast.


CSS - AccountsDataToDisplay.css

body{
   color: #000;
   padding-left: 200px;
}
th {
   text-align: center;
}
td{
   text-align: center;
}
.container{
   display: flex;
   justify-content: center;
}
table{
   width: 50%;
}
.modalTable{
   width: 100%;
}
.viewBtn{
   padding-bottom:10px;
}

XML- AccountsDataToDisplay.js-meta.xml

<?xml   version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>56.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

.Throughout the code walkthrough, we covered various key aspects of the implementation. This included using the wire service to retrieve data from an Apex method, processing and mapping the data for efficient usage, handling user interactions, and incorporating modal functionality for displaying additional details and navigation.


Remember, this code serves as a foundation that you can build upon and customize to suit your specific needs. Salesforce's extensive documentation and developer resources are great references for exploring additional LWC capabilities and best practices.

We hope you found this blog post informative and inspiring. Feel free to experiment with the code, add your own features, and continue exploring the world of Lightning Web Components.


We hope this blog post provided you with valuable insights into building a Lightning Web Component for fetching and displaying account and contact data in Salesforce. By leveraging the power of LWC, you can create dynamic and interactive user interfaces to enhance the user experience.


If you'd like to see the code and resources used in this project, you can access the repository on GitHub.To access the AVENOIRBLOGS repository, click here. Feel free to explore the code and use it as a reference for your own projects.


Happy Coding! You can leave a comment to help me understand how the blog helped you. If you need further assistance, please contact us. You can click "Reach Us" on the website and share the issue with me.


Blog Credit:

N. Mehra

Salesforce Developer

Avenoir Technologies Pvt. Ltd.


Reach us: team@avenoir.ai


Recent Posts

See All

© 2024 by Avenoir Technologies Pvt. Ltd.

bottom of page