Monday, May 16, 2022

Lightning Data Table to Show Parent object data along with Count of the child in LWC Salesforce

Hello Guys, in this post we would learn how can we show Parent object data along with no of child in one column in Lightning data table in Lightning Web Component(LWC).

To understand this scenario, I have taken Account as a parent object and contact as a child object and in the Lightning Data table we would display few Account fields along with No of Contacts

Please check the full code below

Apex Class

public class LightningDataExampleController {
	@AuraEnabled
    public static List getAccounts(){
        return [SELECT Id, Name, AccountNumber, Site,
                (SELECT Id FROM Contacts) 
                FROM Account 
                LIMIT 5];
    }
}
lightningDataTableExample.html

<template>
    <lightning-card title="Lightning Data Table">        
        <div class="slds-grid slds-no-flex slds-var-p-around_medium	">
            <div class="slds-col slds-size_12-of-12">
                <lightning-datatable key-field="Id"
                                    data={accounts}
                                    columns={columns}                                    
                                    hide-checkbox-column
                                    >
                </lightning-datatable>                            
            </div>
        </div>
    </lightning-card>    
</template>
lightningDataTableExample.js

import { LightningElement } from 'lwc';
import getAccounts from '@salesforce/apex/LightningDataExampleController.getAccounts';

export default class LightningDataTableExample extends LightningElement {
    columns = [
        {label: 'Name', fieldName: 'Name', type: 'text', sortable: false},
        {label: 'Account Number', fieldName: 'AccountNumber', type: 'text', sortable: false},
        {label: 'Site', fieldName: 'Site', type: 'text', sortable: false},
        {label: 'No of Contacts', fieldName: 'noOfContacts', type: 'text', sortable: false},
    ];

    accounts = [];
    error;

    connectedCallback(){
        this.getAccounts();
    }
    getAccounts(){
        getAccounts()
        .then(result =>{            
            result.forEach(element => {
                let noOfContacts = 0;
                if(element.Contacts){
                    element.Contacts.forEach(con =>{
                        noOfContacts++;
                    })
                }
                element.noOfContacts = noOfContacts;
            });
            this.accounts = result;            
        })
        .catch(error =>{
            this.error = error;
        })
    }
}
lightningDataTableExample.js-meta.xml

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

Please comment below, if you guys have any quesiton. I'll be happy to answer. Thanks!

Related Posts
Add Delete rows dynamically in Lightning Data Table in LWC Salesforce

Sunday, May 15, 2022

Add Delete rows dynamically in Lightning Data Table in LWC Salesforce

Hello Guys, in this post we'll learn how to add delete rows dynamically in Lightning Data table in Lightning Web Components(LWC) in Salesforce with the proper Example.

Apex Class

public class AddDeleteRowLWCController {

    @AuraEnabled
    public static List getAccounts(){
        return [SELECT Id, Name, AccountNumber, Site FROM Account LIMIT 5];
    }
    @AuraEnabled
    public static Account addAccount(String account){
        Account accObj = (Account) System.JSON.deserialize(account, Account.class);
        insert accObj;
        return accObj;
    }
}
addDeleteRowLWC.html

<template>
    <lightning-card title="">
        <lightning-button variant="brand" label="Add Account" onclick={openAddAccountModal} ></lightning-button>
        <div class="slds-grid slds-no-flex slds-var-p-around_medium	">
            <div class="slds-col slds-size_12-of-12">
                <lightning-datatable key-field="Id"
                                    data={accountData}
                                    columns={columns}
                                    onrowaction={handleRowAction}
                                    hide-checkbox-column
                                    >
                </lightning-datatable>                            
            </div>
        </div>
    </lightning-card>

    <template if:true={isModalOpen}>
        <!-- Modal/Popup Box LWC starts here -->
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
                <!-- Modal/Popup Box LWC header here -->
                <header class="slds-modal__header">
                    <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={closeModal}>
                        <lightning-icon icon-name="utility:close"
                            alternative-text="close"
                            variant="inverse"
                            size="small" ></lightning-icon>
                        <span class="slds-assistive-text">Close</span>
                    </button>
                    <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Add Account</h2>
                </header>
                <!-- Modal/Popup Box LWC body starts here -->
                <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                    <lightning-input name="accountName" type="text"  label="Name" value={accountName} onchange={handleChange}></lightning-input>                    
                    <lightning-input name="accountNumber" type="Integer" label="AccountNumber" value={accountNumber} onchange={handleChange}></lightning-input>                    
                    <lightning-input name="accountSite" type="text" label="Site" value={accountSite} onchange={handleChange}></lightning-input>                    

                </div>
                <!-- Modal/Popup Box LWC footer starts here -->
                <footer class="slds-modal__footer">
                    <button class="slds-button slds-button_neutral" onclick={closeModal} title="Cancel">Cancel</button>
                    <button class="slds-button slds-button_brand" onclick={addAccount} title="Add Account">Add Account</button>
                </footer>
            </div>
        </section>
        <div class="slds-backdrop slds-backdrop_open"></div>
    </template>

</template>
addDeleteRowLWC.js

import { LightningElement } from 'lwc';
import getAccounts from '@salesforce/apex/AddDeleteRowLWCController.getAccounts';
import addAccount from '@salesforce/apex/AddDeleteRowLWCController.addAccount';

export default class AddDeleteRowLWC extends LightningElement {
    columns = [
        {label: 'Name', fieldName: 'Name', type: 'text', sortable: true},
        {label: 'Account Number', fieldName: 'AccountNumber', type: 'text', sortable: false},
        {label: 'Site', fieldName: 'Site', type: 'text', sortable: true},
        {type: "button-icon", typeAttributes: {iconName: "utility:delete", name: "delete", iconClass: "slds-icon-text-error"},fixedWidth: 50}     
    ];

    accountData = [];
    isModalOpen = false;
    accountName= '';
    accountNumber = '';
    accountSite = '';

    connectedCallback(){
        this.getAccounts();
    }
    getAccounts(){
        getAccounts()
        .then(result =>{
            this.accountData = result;
        })
        .catch(error =>{

        })
    }

    handleRowAction(event) {
		if (event.detail.action.name === "delete") {
			this.deleteSelectedRow(event.detail.row);
		}
	}
    deleteSelectedRow(deleteRow) {
		let newData = JSON.parse(JSON.stringify(this.accountData));
		newData = newData.filter((row) => row.Id !== deleteRow.Id);
        this.accountData = newData;		
	}
    openAddAccountModal(){
        this.isModalOpen = true;
    }
    closeModal() {        
        this.isModalOpen = false;
    }
    handleChange(event){
        if(event.target.name == 'accountName'){
            this.accountName = event.target.value;
        }else if(event.target.name == 'accountNumber'){
            this.accountNumber = event.target.value;
        }else if(event.target.name == 'accountSite'){
            this.accountSite = event.target.value;
        }
    }
    addAccount(){
        let accountToInsert = {
            Name : this.accountName,
            AccountNumber: this.accountNumber,
            Site : this.accountSite
        }
        addAccount({
            account: JSON.stringify(accountToInsert)
        })
        .then(result =>{            
            this.addAccountToList(result)
        })
        .catch(error =>{
            this.error = error;
        })        
    }
    addAccountToList(account){
        let localList;            
        if(this.accountData.length > 0){                        
            localList =JSON.parse(JSON.stringify(this.accountData));                
        }else{
            localList = [];                
        }
         
        localList.push({
            Id: account.Id,
            Name : account.Name,
            AccountNumber : account.AccountNumber,
            Site : account.Site,            
        })                                        
        this.accountData = localList;
        this.isModalOpen = false;    
    }
}
addDeleteRowLWC.js-meta.xml

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

If you guys have any question, please comment below, I'll be happy to answer your question.
#LWC, #LightningDataTable, #adddeleterowinlwc #salesforce #salesforcelightning

Related Posts
Lightning Data Table to Show Parent object data along with Count of the child in LWC Salesforce

Friday, May 13, 2022

Subscript is invalid because list is empty | Error in VF Page | Salesforce

Subscript is invalid because list is empty this error is comes on VF page if we are trying to access the list element on VF Page and in the apex the list has no rows.

Below is the example 

Here is my Apex Class

public Class myClass {

    public Account account {get;set;} 

public myClass(){

        recordId = System.currentPageReference().getParameters().get('recordId');

        this.account = [SELECT Id, Name,(select id,LastName FROM Contacts) FROM Account WHERE Id =:recordId];                

    }

}


VF Page

<apex:page renderAs="pdf" applyBodyTag="false" controller="myClass" >

<div class="header">

        <table>         

            <tr>

                <td style="background: #D6EEEE"><b>Account Name</b></td>   

                <td>{!account.Name}</td> 

                <td style="background: #D6EEEE"><b>Contact Last Name</b></td>  

                <td>{!account.Contacts[0].LastName}</td> 

        </tr>

    </table>



In order to solve this error we'll have to modify our code as below

public Class myClass {

    public Account account {get;set;} 

    public String contactLastName {get;set;}

public myClass(){

        recordId = System.currentPageReference().getParameters().get('recordId');

        contactLastName = '';

        this.account = [SELECT Id, Name,(select id,LastName FROM Contacts) FROM Account WHERE Id =:recordId];           

    if(this.account.contacts.size() >0){

        contactLastName = this.account.contacts[0].LastName;

    }     

    }

}


VF Page

<apex:page renderAs="pdf" applyBodyTag="false" controller="myClass" >

<div class="header">

        <table>         

            <tr>

                <td style="background: #D6EEEE"><b>Account Name</b></td>   

                <td>{!account.Name}</td> 

                <td style="background: #D6EEEE"><b>Contact Last Name</b></td>  

                <td><!--{!account.Contacts[0].Name}-->{!contactLastName}</td> 

        </tr>

    </table>


Hope this will solve your problem, Please comment below if you have any question. I'll be happy to help.