6

My wrapper class returns sObjects of type account and contact along with other fields, to my LWC. I am not able to display the data using lightning datatable as something like fieldName:'AccountId.Name' does not work.

I don't want to change the apex class or add any static javascript resource. I understand that I have to flatten the data but I am not sure how and where to do it in my code. I referred this and this solution but it's for lighting component and not LWC. Please guide. Thanks!


Data

Data


Javascript

const actions = [
    { label: 'View', name: 'view' },
    { label: 'Edit', name: 'edit' },
    { label: 'Delete', name: 'delete' },
];

const columns = [
    {
        type: 'action',
        typeAttributes: { rowActions: actions },
    },
    { label: 'Name', fieldName: 'AccountId.Name', type: 'text' },
    //{ label: 'Api Name', type: 'button', typeAttributes: { label:  {fieldName: 'apiName'}, variant: 'base' } },
    { label: 'AccountName', fieldName: 'Name', type: 'text' },
    { label: 'Role', fieldName: 'ContactRole', type: 'text' },
    { label: 'IsPrimary', fieldName: 'IsPrimary', type: 'boolean', editable: 'true' },
    { label: 'MDM ID', fieldName: 'MDM_ID', type: 'text' },
];


export default class ContactRelatedAccount extends NavigationMixin(LightningElement) {
    @api recordId;
    @track columns = columns;
    @track addresses;
    @track record = [];
    refreshTable;
    res;

    @wire(getAddress, { LeadID: '$recordId' }) wired(result) {
        this.refreshTable = result;
        if (result.data) {
            this.addresses = result.data;
        }
        if (result.error) {
            this.error = result.error;
        }
    }
}

1
  • 1
    The array can be flattened at client side, doing it at server side would be better and cleaner, so why not change the apex structure.
    – Raul
    Dec 5, 2019 at 8:08

3 Answers 3

13

you can prepare data before passing it to lightning-datatable

@wire(getAddress, { LeadID: '$recordId' }) wired(result) {
    this.refreshTable = result;
    if (result.data) {
        this.addresses = result.data.map((elem) => ({
                ...elem,
                ...{
                    'Account_Id': elem.AccountId.Id,
                    'Account_Name': elem.AccountId.Name,
                    'Contact_Id': elem.ContactID.Id,
                    'Contact_Name': elem.ContactID.Name,
                    'Contact_Title': elem.ContactID.Title
                    // and so on for other fields
                }
        }));
    }
    if (result.error) {
        this.error = result.error;
    }
}

after that set column with names of fields from result.data.map function

const columns = [
    {
        type: 'action',
        typeAttributes: { rowActions: actions },
    },
    { label: 'Account Id', fieldName: 'Account_Id', type: 'text' },
    { label: 'Account Name', fieldName: 'Account_Name', type: 'text' },
    { label: 'Contact Id', fieldName: 'Contact_Id', type: 'text' },
    { label: 'Contact Name', fieldName: 'Contact_Name', type: 'text' },
    { label: 'Contact Title', fieldName: 'Contact_Title', type: 'text' }
];
1
  • 3
    Nitpick - I think it would be more idiomatic javascript to use map instead of foreach. if(result.data) this.addresses = result.data.map(callback to create the flattened object)
    – adriancg
    May 19, 2020 at 17:24
6

You can use this component.

Sample: (Notice how we got CreatedBy.Name below)

<template>
    <c-datatable config={config}>
    </c-datatable>
</template>

and its JS:

import { LightningElement, track } from 'lwc';

export default class PocTable extends LightningElement {
    config = {
        objectName: "Account",
        tableConfig: {
            columns: [
                { api: 'Name', label: 'Name', fieldName: 'Name', sortable: true },
                { api: 'CreatedDate', label: 'Created On', fieldName: 'CreatedDate', type: 'date', sortable: true },
                { api: 'CreatedBy.Name', label: 'Created By', fieldName: 'CreatedByName', sortable: true }
            ]
        }
    };
}

NOTE: You need add api property in columns which will be used to fetch data from database.

More information - lightning datatable (AURA or LWC) can automatically fetch records from database?

0
3

You can easily build the flatten model for use with the data table using the javascript function Object.assign() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.

@wire(getProductsWithPriceInfo, {
    opportunityId: "$recordId"
})
getProducts(result) {
    this.wiredProductResult = result;
    this.allProducts = [];

    if (result.data) {
        for (let i = 0; i < result.data.length; i++) {
            let row = result.data[i];
            this.allProducts = [
                ...this.allProducts,
                Object.assign(
                    {
                        ProductName: row.Product2.Name,
                        ProductFamily: row.Product2.Family,
                        ProductCode: row.Product2.ProductCode,
                        ProductDescription: row.Product2.Description
                    },
                    row
                )
            ];
        }

        this.products = this.allProducts;

        this.error = undefined;
    } else if (result.error) {
        this.error = result.error;
        this.allProducts = undefined;
        this.products = undefined;
    }
}

You must log in to answer this question.

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