As I have written more LWC components, I've generally found that things work best when you stick with the reactive model as much as possible, and that by properly writing your getters to gracefully handle not-yet-ready data, it's possible (and better) to wire most Cachable
Apex to properties instead of functions. For example:
import { LightningElement, api, wire } from 'lwc';
import getInitialData from '@salesforce/apex/MyController.getInitialData';
export default class ComponentExample extends LightningElement {
@api recordId;
@wire(getInitialData, {recordId: '$recordId}) initialDataResponse;
get recordData() {
return this.initialDataResponse?.data;
}
get errorMessage() {
return this.initialDataResponse?.error?.body.message;
}
get hasError() {
return !!this.initialDataResponse?.error;
}}
// etc...
}
As I've gotten used to this style, I've found that I almost never need to wire an apex method to a JS function. Where I'm having an issue is long-running methods, where I'd like to show a spinner while the data is fetched. In the simplest case of loading data when the component loads, I've done something like this:
export default class ComponentExample extends LightningElement {
@api recordId;
showSpinner = true;
initialDataResponse;
@wire(getInitialData, {recordId: '$recordId}) wiredResponse(initialDataResponse) {
this.initialDataResponse = initialDataResponse;
this.showSpinner = false;
}
This works, but only at load time, and it requires wiring a function. If a dynamic parameter changes (recordId
in the example), I have no way to set showSpinner = true
before LDS calls Apex, as the wired function is only called when the apex call completes.
What I'd really like is to receive an event whenever LDS calls the wired method to re-provision the data, and an event when the fetch is complete, so that I can manage my spinner accordingly. And while in some cases I can simply derive a "showSpinner" value from the data in the page, I often use a hierarchy of components, where I'd like subcomponents to fire a server
event with a start
or stop
payload, and let the parent component manage the spinner at the parent level. I can find no way to fire events when a computed value (getter) changes.
I haven't found any way to achieve this level of granularity with LDS. Is it possible?