I created the custom Product2 lookup field on WorkOrderLineItem. Custom Lookup Field in LWC Datatable is not showing data in the column. The field is editable, and the data is saved after changed.
The problem is only with custom field, the standard field, where I am using AssetId is working correct.
Can you please check if I wrote the 'Columns' and @wire correct?
import { LightningElement, track, wire, api } from 'lwc';
import fetchWolis from '@salesforce/apex/AccountDataController.fetchWolis';
import WORK_ORDER_LINE_ITEM_OBJECT from '@salesforce/schema/WorkOrderLineItem';
import STATUS_FIELD from '@salesforce/schema/WorkOrderLineItem.Status';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';
import { getPicklistValues, getObjectInfo } from 'lightning/uiObjectInfoApi';
const columns = [
{
label: 'Device',
fieldName: 'AssetId',
type: 'lookupColumn',
typeAttributes: {
object: 'WorkOrderLineItem',
fieldName: 'AssetId',
value: { fieldName: 'AssetId' },
context: { fieldName: 'Id' },
name: 'Asset',
fields: ['Asset.Name'],
target: '_self'
},
editable: false,
},
{
label: 'Serial Number', fieldName: 'Serial_No__c', editable: false
},
{
label: 'Status', fieldName: 'Status', type: 'picklistColumn', editable: false, typeAttributes: {
placeholder: 'Choose Status', options: { fieldName: 'pickListOptions' },
value: { fieldName: 'Status' }, // default value for picklist,
context: { fieldName: 'Id' } // binding account Id with context variable to be returned back
}
},
{ label: 'Product', fieldName: 'PricebookEntryId', editable: false },
{
label: 'Product',
fieldName: 'ProductXX__c',
type: 'lookupProduct',
typeAttributes: {
object: 'WorkOrderLineItem',
fieldName: 'ProductXX__c',
value: { fieldName: 'ProductXX__c' },
context: { fieldName: 'Id' },
name: 'Product2',
fields: ['Product2.Name'],
target: '_self'
},
editable: false,
},
{ label: 'Qauantity', fieldName: 'Quantity', editable: true},
{ label: 'List Price', fieldName: 'ListPrice', type: 'currency', editable: false},
{ label: 'Discount %', fieldName: 'Discount', type: 'percent-fixed', editable:true,
cellAttributes: {
alignment: 'left'
},
},
{ label: 'Total Price', fieldName: 'TotalPrice', type: 'currency', editable: false },
{
label: 'Line Item Number',
fieldName: 'nameUrl',
type: 'url',
typeAttributes: {label: { fieldName: 'LineItemNumber' },
target: '_blank'},
sortable: true
}
]
export default class CustomDatatableDemo extends LightningElement {
columns = columns; //picklist
showSpinner = false;
@track data = [];
@track accountData;
@track draftValues = [];
lastSavedData = [];
@track pickListOptions;
@api recordId; //related record
@wire(getObjectInfo, { objectApiName: WORK_ORDER_LINE_ITEM_OBJECT })
objectInfo;
//fetch picklist options
@wire(getPicklistValues, {
recordTypeId: '0120X000000gLE8QAM',
fieldApiName: STATUS_FIELD
})
wirePickList({ error, data }) {
if (data) {
this.pickListOptions = data.values;
} else if (error) {
console.log(error);
}
}
//here I pass picklist option so that this wire method call after above method
@wire(fetchWolis, { woid: '$recordId' }, { pickList: '$pickListOptions' })
accountData(result) {
this.accountData = result;
if (result.data) {
let baseUrl = 'https://'+'demant--andzeladev.lightning.force.com'+'/';
this.data = JSON.parse(JSON.stringify(result.data));
console.log(this.data);
this.data.forEach(ele => {
ele.pickListOptions = this.pickListOptions;
ele.nameUrl = baseUrl+ele.Id;
// ele.assetUrl = baseUrl+ele.AssetId;
// ele.serialUrl = baseUrl+ele.AssetId;
ele.accountLink = ele.AssetId != undefined ? '/' + ele.AssetId : '';
ele.accountName = ele.AssetId != undefined ? ele.Asset.Name : '';
ele.productLink = ele.ProductXX__c != undefined ? '/' + ele.ProductXX__c : '';
ele.productLink = ele.ProductXX__c != undefined ? ele.Product2.Name : '';
})
this.lastSavedData = JSON.parse(JSON.stringify(this.data));
} else if (result.error) {
this.data = undefined;
}
};
updateDataValues(updateItem) {
let copyData = JSON.parse(JSON.stringify(this.data));
copyData.forEach(item => {
if (item.Id === updateItem.Id) {
for (let field in updateItem) {
item[field] = updateItem[field];
}
}
});
//write changes back to original data
this.data = [...copyData];
}
updateDraftValues(updateItem) {
let draftValueChanged = false;
let copyDraftValues = [...this.draftValues];
//store changed value to do operations
//on save. This will enable inline editing &
//show standard cancel & save button
copyDraftValues.forEach(item => {
if (item.Id === updateItem.Id) {
for (let field in updateItem) {
item[field] = updateItem[field];
}
draftValueChanged = true;
}
});
if (draftValueChanged) {
this.draftValues = [...copyDraftValues];
} else {
this.draftValues = [...copyDraftValues, updateItem];
}
}
//listener handler to get the context and data
//updates datatable
picklistChanged(event) {
event.stopPropagation();
let dataRecieved = event.detail.data;
let updatedItem = { Id: dataRecieved.context, Status: dataRecieved.value };
console.log(updatedItem);
this.updateDraftValues(updatedItem);
this.updateDataValues(updatedItem);
}
lookupChanged(event) {
console.log(event.detail.data);
event.stopPropagation();
let dataRecieved = event.detail.data;
let accountIdVal = dataRecieved.value != undefined ? dataRecieved.value : null;
let updatedItem = { Id: dataRecieved.context, AssetId: accountIdVal };
console.log(updatedItem);
this.updateDraftValues(updatedItem);
this.updateDataValues(updatedItem);
}
lookupproductchanged(event) {
console.log(event.detail.data);
event.stopPropagation();
let dataRecieved = event.detail.data;
let productIdVal = dataRecieved.value != undefined ? dataRecieved.value : null;
let updatedItem = { Id: dataRecieved.context, ProductXX__c: productIdVal };
console.log(updatedItem);
this.updateDraftValues(updatedItem);
this.updateDataValues(updatedItem);
}
//handler to handle cell changes & update values in draft values
handleCellChange(event) {
this.updateDraftValues(event.detail.draftValues[0]);
}
handleSave(event) {
this.showSpinner = true;
this.saveDraftValues = this.draftValues;
const recordInputs = this.saveDraftValues.slice().map(draft => {
const fields = Object.assign({}, draft);
return { fields };
});
// Updateing the records using the UiRecordAPi
const promises = recordInputs.map(recordInput => updateRecord(recordInput));
Promise.all(promises).then(res => {
this.showToast('Success', 'Records Updated Successfully!', 'success', 'dismissable');
this.draftValues = [];
return this.refresh();
}).catch(error => {
console.log(error);
this.showToast('Error', 'An Error Occured!!', 'error', 'dismissable');
}).finally(() => {
this.draftValues = [];
this.showSpinner = false;
});
}
handleCancel(event) {
//remove draftValues & revert data changes
this.data = JSON.parse(JSON.stringify(this.lastSavedData));
this.draftValues = [];
}
showToast(title, message, variant, mode) {
const evt = new ShowToastEvent({
title: title,
message: message,
variant: variant,
mode: mode
});
this.dispatchEvent(evt);
}
// This function is used to refresh the table once data updated
async refresh() {
await refreshApex(this.accountData);
}
}