7

I'm trying to implement a refresh button in one of my components. I'm using the @wire decorator with getListUi to get a list of records for each of which I'm rendering a component. The @wire method calls when the component is mounted, but I also want to call it when I hit a reload button in the UI. Any idea how to achieve this? Here is what I have so far: (Not working)

import { LightningElement, track, wire } from 'lwc';
import { getListUi } from 'lightning/uiListApi';
import CONTENT_OBJECT from '@salesforce/schema/Content_Item__c';

export default class DayCards extends LightningElement {
    @track contentItems;
    @track error;

    @wire(getListUi, {objectApiName: CONTENT_OBJECT, listViewId: '00B9A000001AitaUAC' })
    wiredContent({error, data}) {
        if (data) {
            this.contentItems = data.records.records;
            console.log('data: ', data.records.records);
        } else if (error) {
            console.log('error: ', error);
        }
    }

    reloadItems(event) {
        console.log('refreshing');
        this.wiredContent(); // I want to call the @wire method again here
    }

}

<template>
    <div class="day-cards slds-p-around_medium slds-box slds-box_small">
        <div if:true={error}>{error}</div>
        <div class="refresh-button">
            <lightning-button-icon icon-name="action:refresh" variant="bare" alternative-text="Refresh" icon-class="slds-m-around_medium"
                onclick={reloadItems}></lightning-button-icon>
        </div>
        <template for:each={contentItems} for:item="item">
            <c-day-card key={item.fields.Id.value} date={item.fields.Date__c.value} description={item.fields.Description__c.value}
                link-url={item.fields.Redirect_URL__c.value}></c-day-card>
        </template>
    </div>
</template>
0

4 Answers 4

5

getListUi from lightning/uiListApi doesn't support imperative refresh or invocation in Spring 19. That wire adapter is in beta for the Spring 19 release (per https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_lightning_ui_api_list_ui).

We're actively working on a feature whereby Lightning Data Service (and all of its @wire adapters) will automatically provision a new version of records when they're changed in any technology: LWC, Aura, Visualforce, Apex, triggers, etc. This means your components are reactive to record data changes regardless of the source. It also eliminates your need as a developer to know when to refresh which records. There's an open pilot for this; contact your account / support manager to join the Live Records pilot. We also have some other changes coming that'll make working with lists of records in LWC easier.

In the meantime you could replace your use of getListUi with Apex and SOQL, and use refreshApex from @salesforce/apex to imperatively refresh the Apex @wire adapter as required. See the code sample at https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex.

4
  • So in other words it can only be used with hardcoded list views and sobject types? How is that even useful?
    – dzh
    Mar 22, 2019 at 3:37
  • @dzh you don’t have to use the schema imports; see developer.salesforce.com/docs/component-library/documentation/…. That explains the benefit and tradeoff of schema imports. Mar 22, 2019 at 4:35
  • @KevinVenkiteswaran any update on this? I have getListUi working with wire, but I don't have a way to refresh the records when the list view changes. Dec 7, 2020 at 19:43
  • 1
    We had to re-approach the problem from another angle. We're working to expose an <adapter>NotifyChange(...) function for each wire adapter. We've trialed this with getRecordNotifyChange() which is documented at developer.salesforce.com/docs/component-library/documentation/…. I expected other adapters to see a comparable function in the next couple of releases. Support for getListUi will come later after some much-needed refactoring. Dec 9, 2020 at 3:43
2

You can just imperatively call refreshApex as explained in the docs: https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex

import { refreshApex } from '@salesforce/apex';
refreshApex(wiredProperty)
1
  • 1
    I believe refreshApex is intended for cache busting, and will only work if the Apex method is annotated with cacheable=true. Tushar's suggestion of calling the Apex method imperatively would work in any scenario. Dec 28, 2018 at 20:12
2

If the above method didn't work for you. Then you can call apex method imperatively

handleLoad() {
        getListUi({objectApiName: CONTENT_OBJECT, listViewId: '00B9A000001AitaUAC' })
            .then(result => {

            })
            .catch(error => {
                this.error = error;
            });
    }

https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex

1
1

You can change the value of any argument to the getListUi api and it will automatically call the wire method again.
To elaborate on this, as mentioned in the documentation: here
The getListUi can take any of the following parameters:

  1. objectApiName
  2. listViewApiName
  3. sortBy
  4. pageSize
  5. pageToken

Now if you change the value of any 1 variable that is assigned to these parameters the getListUi will automatically be triggered to fetch the new results.
Considering the usecase mentioned in the question, it seems that the objectApiName, listViewApiName will be constant. Hence as a workaround, you can try changing the value of variables holding the pageSize or sortBy to retrigger the fetch of records.

Note: This is useful when we need to fetch different listviews of different objects and changing pageSize or sortBy will only serve as a workaround.
Sample code:

pageSize = 10;
selectedObject = 'Account';
selectedListView = 'All';

@wire(getListUi, {
    objectApiName: '$selectedObject',
    listViewApiName: '$selectedListView',
    pageSize: '$pageSize',
    pageToken: '$pageToken'
})
wiredlistView(result) {
    if (result.data) {
        // do somethings
    } else if (result.error) {
        // do something
    }
}

handleButtonClick() {
    this.pageSize = 11; //will call getListUi again
}
2
  • Could you please expand your answer a little to explain how this could help to resolve the original problem? Jun 30, 2021 at 12:27
  • 1
    I have elaborated my answer Jul 1, 2021 at 8:12

You must log in to answer this question.

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