2

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
    Commented Nov 23, 2021 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
    Commented Nov 23, 2021 at 10:13

2 Answers 2

3

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
    Commented Nov 23, 2021 at 6:47

You must log in to answer this question.

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