5

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 '19 at 8:08
11

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 '20 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;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.