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
    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
    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
    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 .