0

I have a lighting web component datatable that is populated from and @wire call. Below are the key snippets from my code

import { LightningElement, api, wire, track } from 'lwc';
import getOrderlines from '@salesforce/apex/PP_OrderController.getOrderlines';
import { refreshApex } from '@salesforce/apex';
..

export default class Orderlines extends LightningElement {

   @api orderId;
  @track wiredDataResult;

...
 @wire(getOrderlines, {orderId: '$orderId'}) processOrderline({data, error}) {
        this.wiredDataResult = data;
        this.orderlines = this.wiredDataResult.listOliWrapper;

...

This is used to populate a datatable:

<lightning-datatable
        key-field="orderLineId"
        data={orderlines}
        columns={columns}
        onsave={handleSave}
        draft-values={draftValues}
        hide-checkbox-column>
    </lightning-datatable>

This is all working fine.

In the handleSave() after sending the update to apex controller (which saves fine), I'm trying to refresh the page using refreshApex

 refreshApex(this.wiredDataResult).then(() => {
       //Clear all draft values in the datatable
       this.draftValues = [];
 }); 

However, I'm getting error from above line as the promise is not being handled. Error:

TypeError: Cannot read properties of undefined (reading ‘then’)“. 

I've tried rewriting the @wire to :

@wire(getOrderlines, {
        orderId: ‘$orderId’
    }) processOrderline( result) {
        console.log(‘result’ + JSON.stringify(result));
        console.log(‘result.data ’ + JSON.stringify(result.data));
        this.wireResult = result;
        this.wiredDataResult = result.data;
        this.orderlines = this.wiredDataResult.listOliWrapper;

so that I can call the refresh apex on wireResult (rather than the data part only):

refreshApex(this.wireResult).then(() => {
                 //Clear all draft values in the datatable
                this.draftValues = [];
            }); 

However with this approach the @wire is not populating the result object. In the console.log message in the promise I'm getting:

result{}
result.data undefined 

and thus the table is not showing on screen.

Any ideas or how to fix this?

2
  • 2
    The wire function is called first with an empty result and later with either data or error content. Make sure you allow for this.
    – Phil W
    Nov 23 '21 at 6:22
  • Thanks @PhilW - this helped, I didn't know that it was called first with empty result. I was not handling the first one properly
    – Amul Shah
    Nov 23 '21 at 10:13
2

Thanks to @PhilW for the tip 'The wire function is called first with an empty result and later with either data or error content.' I was not aware of that and I was not handling the first empty result properly.

Updated the code to

@wire(getOrderlines, {orderId: '$orderId'}) processOrderline(result) {

    this.wiredResult = result;
    const { data, error } = result;
    
    if (data) { ...

And then refresh apex to

refreshApex(this.wiredResult).then(() => {
    //Clear all draft values in the datatable
   this.draftValues = [];
}); 

Works now!

0

If processOrderline({data, error}) is giving you data, result.data also should give you.. This is just standard deconstruction in js

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

You may need to check PP_OrderController.getOrderlines and what is value of orderId

1
  • PP_OrderController.getOrderlines is unchanged between the two versions of the call.
    – Amul Shah
    Nov 23 '21 at 6:47

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.