0

I have assigned one POC in which I need to display contact list on datatable by clicking preview icon of account record in searched accounts list. I'm using datatable row action for icon click but I'm facing challenge while passing accountId from handleRowAction to @wire (getAccountAndRelatedContacts, {accountId : '$accountId'}).
Is there any way to pass Account Id from preview icon or to fetch Id's for account records and pass them to @wire for displaying contacts. I'm trying hard to achieve this and even go through many online solutions but didn't get expected results. Any Suggestions ?

Here is my apex class

public with sharing class AccountCalloutService1 {
    public static Http http = new Http();
    public static HTTPResponse response;
    public static HttpRequest request;
 
    public class NewAccountRequestWrapper {
        @AuraEnabled public String firstName {get; set;}
        @AuraEnabled public String lastName {get; set;}
        @AuraEnabled public String email {get; set;}
        @AuraEnabled public String phone {get; set;}
    }

    @AuraEnabled (cacheable=true)
    public static List<Account> searchAccounts(String keySearch){
        String strAccName = keySearch + '%';
        List<Account> accList = [SELECT Id, Name, Type, Phone, Industry, Website FROM Account WHERE Name LIKE: strAccName];        
        return accList;
    }    
    
    @AuraEnabled (cacheable=true)
    public static List<Contact> getAccountAndRelatedContacts(String accountId) {
        
        List<Contact> allConList = new List<Contact>();
        request = new HttpRequest();
        request.setMethod('GET');
        request.setEndpoint('callout:Org2API/services/apexrest/v1/Contacts/' + accountId);
        request.setTimeout(120000);
            
        response = http.send(request); 
        System.debug('=='+response.getBody());
        List<Contact> conList = (List<Contact>)JSON.deserialize(response.getBody(), List<Contact>.class);            
        allConList.addAll(conList);
        return allConList;     
    }
}

Here is my LWC js

import { LightningElement, track, wire } from 'lwc';
import getAccountAndRelatedContacts from '@salesforce/apex/AccountCalloutService1.getAccountAndRelatedContacts';
import searchAccounts from '@salesforce/apex/AccountCalloutService1.searchAccounts';
import { refreshApex } from '@salesforce/apex';
const columnList = [
    {label: 'Action', type: 'button-icon', fieldName: 'Id',
        typeAttributes : {iconName : 'utility:preview', name : 'preview'}
    },    
    {label : 'Account Name', fieldName : 'Name', type: 'text', sortable: true},
    {label : 'Account Type', fieldName : 'Type', type: 'text', sortable: true},
    {label : 'Phone', fieldName : 'Phone'},
    {label : 'Industry', fieldName : 'Industry', type: 'text', sortable: true},
    {label : 'Website', fieldName : 'Website'},
];

export default class DispExtDataOnAccountSearch1 extends LightningElement {
    
    //For icons
    @track showDetails = false;
    @track showRightBtn = true;
    @track showDownbtn = false;

    @track currentAccountName;
    @track searchAccountId;

    //For account
    @track accountList = [];    
    @track accountError;
    @track columnList = columnList;
    @track accountData = true;
    @track dataNotFoundForAccount;

    //For Contact data
    @track contactsData = [];
    @track dataNotFoundForExtContact;
    @track extContactData = false;

    handleChangeAccName(event){
        this.currentAccountName = event.target.value;   
        const keySearch = event.target.value;

        if(keySearch) {
            searchAccounts({keySearch})
            .then(result => {
                this.accountList = result;
                this.accountError = undefined;
                this.accountData = true;                          
                this.dataNotFoundForAccount = '';
                if(this.accountList == ''){
                    this.accountData = false; 
                    this.dataNotFoundForAccount = 'There is Account found with Searched name';
                }        
            })
        }else {
            this.accountError = error;
            this.accountList = undefined; 
            this.accountData = false;          
        } 
      }
    
    //For related data
    @wire (getAccountAndRelatedContacts, {accountId : '$accountId'}) 
    wireRecord(result){
        const { data, error } = result;
        if(data){         
            this.contactsData = data; 
            console.log('con:'+this.contactsData);
            this.error = undefined;
            this.dataNotFoundForExtContact = '';
            if(this.contactsData == ''){
                this.extContactData = false; 
                this.dataNotFoundForExtContact = 'There is no Contact found related to Account name';
            }        
            
        }else{
            this.error = error;
            this.contactsData = undefined;
        }
    }

    handleRowAction( event ) {
        if (event.detail.action.name === 'preview') {
            this.searchAccountName = this.currentAccountName;
            this.extContactData = true;
        }        
    }
}

Here is my LWC html

<template>
    <lightning-card title="Display the External Salesforce Org data based on Account" custom-icon="custom:icon13">
        <div class="slds slds-p-horizontal--medium">
            <div class="slds-grid slds-wrap">
                <div class="slds-col slds-size_4-of-12 slds-m-bottom--medium">
                    <lightning-Input type="search" placeholder="Search..." value={accountName} name="accountName" class="accountName" onchange={handleChangeAccName}></lightning-input>                 
                </div>
                <!--<div class="slds-col slds-size_6-of-12 slds-m-top--medium" style="margin-top: 19px; margin-left: 10px;">                 
                    <lightning-button label="Search Account" size="small" variant="brand" onclick={handleAccountSearch} icon-name="utility:search" icon-position="right"></lightning-button>
                </div>-->
            </div>  
            
            <h2 class="slds-m-bottom--x-small" style="color:darkslateblue; font-weight:bold;">Display Account details</h2>  
            <div class="slds-grid slds-wrap">            
                <template if:true={accountData}>                    
                    <lightning-datatable key-field="id" data={accountList} columns={columnList} hide-checkbox-column="true" onrowaction={extContactData}></lightning-datatable>
                </template>
                <template if:false={accountData}>
                    <h3><strong><span style="color:brown;">{dataNotFoundForAccount}</span></strong></h3>
                </template>
            </div><br/>
        
            <h2 class="slds-m-bottom--x-small" style="color:darkslateblue; font-weight:bold;">Displaying External Contact Records based on Account</h2>  
            <template if:true={extContactData}>                  
                <div id="tableBox" class="slds-col slds-size_11-of-12 slds-m-bottom--medium">
                    <table class="slds-table slds-table_cell-buffer slds-table_bordered" border="1px solid #ccc" cellspacing="0" cellpadding="0" style="border-collapse:collapse;">
                        <thead>
                            <tr>
                                <th>First Name</th>
                                <th>Last Name</th>
                                <th>Email</th>
                                <th>Phone</th>                          
                            </tr>
                        </thead>                  
                        <tbody>
                            <template for:each={contactsData} for:item="conItem">
                                <tr key={conItem.Id}>
                                    <td>{conItem.FirstName}</td>
                                    <td>{conItem.LastName}</td>
                                    <td>{conItem.Email}</td>
                                    <td>{conItem.Phone}</td>                        
                                </tr>
                            </template>
                        </tbody>                      
                    </table>
                    
                </div>
            </template>
            <template if:false={extContactData}>
                <h3><strong><span style="color:brown;">{dataNotFoundForExtContact}</span></strong></h3>
            </template>
        </div>
    </lightning-card>           
</template>

Display output should be like this :

enter image description here

like shown here once i preview 1st sForce It will only open the related records associated to that account likewise for 2nd sForce.

1 Answer 1

0

In handleRowAction method you can get the selected row data via event.detail.row. Since it's an account record, it has an Id property that you should put in accountId variable, then the wired method will automatically fire, because wired services are reactive (emphasis mine):

We call the wire service reactive in part because it supports reactive variables, which are prefixed with $. If a reactive variable changes, the wire service provisions new data.

handleRowAction( event ) {
    if (event.detail.action.name === 'preview') {
        const row = event.detail.row; // current row element
        this.accountId = row.Id;
    }
}

You should not set extContactData in that method, but only in the function wireRecord. Moreover since getAccountAndRelatedContacts returns a list of contacts, that may be empty, in order to know if any contact has been found instead of checking if(this.contactsData == ''){ you should check if (!this.contactsData.length) {.
Currently it works because you used == (equality operator) instead of === (strict equality) and equality operator attempts to convert and compare operands that are of different types, so '' == [] returns true. Sp the if (data) block could be written as:

if (data) {         
    this.contactsData = data; 
    console.log('con:', this.contactsData);
    this.error = undefined;
    this.extContactData = this.contactsData.length > 0;
    this.dataNotFoundForExtContact = this.extContactData ? '' : 'There is no Contact found related to Account name';    
}

The same goes for the then block of searchAccounts.

Keep in mind that Javascript is case-sensitive, so id and Id are not the same, therefore you should change the key-field of account datatable to key-field="Id".

Finally you don't need to @track those variables: properties used in the template are already reactive

1
  • Thanks @RubenDG, this worked for me, I've made changes in handleRowAction to get the record Id of a row and made other code amendments as well. The only thing I changed additionally is that, I replaced table with lightning-Datatable and It worked surprisingly well. Sep 1, 2022 at 2:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .