0

I am using LWD lightning data table to display list of accounts from apex controller using imperative apex method call. I see that data is getting set in property {accounts} and even in UI when i check {account.Name} its displaying in UI but the data is not rendering in lightning-data-table

I am getting an empty table even with No columns.

HTML

<template>
    <div class="slds-m-top_medium slds-m-bottom_x-large">
        <h2 class="slds-text-heading_medium slds-m-bottom_medium">
            Search Account with Account Name here.
        </h2>
        <div if:true={isLoaded} class="slds-is-relative">
            <lightning-spinner variant="brand" size="large"> </lightning-spinner>
        </div>
        <lightning-layout-item flexibility="grow">
            <lightning-input type="search" label="Account Name" name="Account Name"
                placeholder="Search Account Name."  class="slds-size_2-of-2 slds-m-left_x-small"
                onchange={handleKeyChange}></lightning-input>
        </lightning-layout-item>
        <lightning-button variant="brand" label="Search" title="Search" onclick={searchAccounts}
            class="slds-m-left_x-small"></lightning-button>
    </div>
    <template lwc:if={accounts}>
        <div style="height: 300px;">
            <lightning-datatable
                    key-field="Id"
                    data={accounts}
                    columns={columns}>
            </lightning-datatable>
        </div>
        </template>
     <!--<c-display-Accounts-In-Table accounts={accounts}></c-display-Accounts-In-Table>-->
     <template lwc:if={accounts}>
        <template for:each={accounts} for:item="account">
            <p key={account.Id}>{account.Name}</p>
        </template>
    </template>
</template>

JS

import { LightningElement,track } from 'lwc';
import getAccountsData from '@salesforce/apex/AccountController.findAccounts';

const columns = [
    { label: 'AccountNumber', fieldName: 'AccountNumber',type: 'text' },
    { label: 'Name', fieldName: 'Name', type: 'text' },
    { label: 'BillingCity', fieldName: 'BillingCity', type: 'text' },
    { label: 'Phone', fieldName: 'Phone', type: 'phone' }
];
export default class FetchAccountDetails extends LightningElement {
    isLoaded;
    eneteredAccountName;
    @track accounts;
    error;

    handleKeyChange(event) {
        //alert(event.target.value)
        this.eneteredAccountName = event.target.value;
    }
    searchAccounts() {
        
        this.isLoaded = true;
        getAccountsData({searchKey: this.eneteredAccountName}).then(result => {
            this.accounts = result;
            this.isLoaded = false;
          })
          .catch((error) => {
            alert(error)
            this.error = error;
            this.isLoaded = false;
          });
    }
   


    
}

Controller

public class AccountController {
    @AuraEnabled(cacheable=true)
    public static List<Account> findAccounts(String searchKey) {
        system.debug('searchKey--->>>>'+searchKey);
        String key = '%' + searchKey + '%';
        return [
            SELECT AccountNumber, Name, BillingCity,Phone
            FROM Account
            WHERE Name LIKE :key
        ];
    }
}
0

1 Answer 1

1

You could only refer class properties in the template, see docs:

Bind properties in a component’s template to properties in the component’s JavaScript class.

columns is a static constant defined only outside of the class, so the datatable cannot access it, that's the issue.

In order to expose it you could use a getter:

const COLUMNS = [
    { label: 'AccountNumber', fieldName: 'AccountNumber',type: 'text' },
    { label: 'Name', fieldName: 'Name', type: 'text' },
    { label: 'BillingCity', fieldName: 'BillingCity', type: 'text' },
    { label: 'Phone', fieldName: 'Phone', type: 'phone' }
];

export default class FetchAccountDetails extends LightningElement {
    isLoaded;
    eneteredAccountName;
    accounts;
    error;
    
    get columns() {
        return COLUMNS;
    }
    
    // rest of the code

I changed the constant to COLUMNS. Keep in mind that Javascript is case-sensitive.

By the way, you don't need @track here. Properties used in the template are already reactive.

3
  • Thanks very much Ruben!! It worked.. Aug 9, 2023 at 10:30
  • One more thing i can also declare the values of columns inside the class right? what would be the diff? Aug 9, 2023 at 10:36
  • @DeepakAgarwal yes, of course the columns definition could be just inside the class, i.e. you could define the array in the getter, having something like return [ { label: 'AccountNumber', fieldName: 'AccountNumber' }, /* and so on */ ];. Everythng inside the class is an instance property, so different instances could have their own values for the same instance property. What lies outside the class is static, therefore shared between instances. Keep in mind that the code should be its own documentation, so if something should be a read-only property, define it using a getter.
    – RubenDG
    Aug 9, 2023 at 14:02

You must log in to answer this question.

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