1

Getting data can be done in at least 2 ways in LWC:

  • Call the apex method imperatively (e.g. in connectedCallback)
  • Wire the apex method

In my use case, data to be fetched is static and is not subject to change when parameters are changed.

@wire(getFieldSetFields, {
    objectName: CASE_SOBJECT.objectApiName,
    fieldSetName: CASE_RECORD_OVERVIEW_FIELDSET_NAME
})
wiredCaseFieldSetFields;

vs

async connectedCallback(){
    const results = await getFieldSetFields({
        objectName: CASE_SOBJECT.objectApiName,
        fieldSetName: CASE_RECORD_OVERVIEW_FIELDSET_NAME
    })
}

Now, my question is: for static data (data not subject to change due to changing variables), what seems the 'best' approach to get the data?

A few things I see:

Pro's for wiring:

  • Code Readability
  • Static data can be cached

Pro's for connectedCallback:

  • No checking if wired property contains data
  • 2
    I note this answer recommends against making the connectedCallback async and suggests a couple of alternatives. However, I see that some of the Salesforce examples (such as that for the lightning-datatable's basic.js do actually do this. – Phil W Aug 5 at 12:29
4

A few points really do matter.

If you use await, your connectedCallback can't proceed until the results come back:

this.result1 = await method1(params);
this.result2 = await method2(params);

This is useful if the order of method calls matter, but usually you just want to go as fast as possible, so wire methods are preferable.

You also need to remember to use try/catch to make sure that errors don't cause the ugly "gray screen of death" errors you get when an uncaught exception occurs. With wire methods, you get this extra try-catch logic for free.

You can also use await in parallel:

// Do not do this if you care about reporting specific errors.
[this.result1, this.result2] = [await method1(params), await method2(params)];

But this is a little more complicated if you get errors.

You can also Promise.all or Promise.allSettled (the latter allows partial success for resolving promises).

Promise.all([method1(params), method2(params)]).then((results)=> {
  // Handle results here
}); 

At the end of the day, the specific circumstances surrounding not just this method, but other methods you may want to call, may determine the choice that you choose.

However, they're all perfectly valid options, and there's not enough of a difference for just a single method to justify overthinking it. Just use whichever you prefer.

Note that none of the pros you mentioned are actually pros for either side, except possibly readability. You still need to check for null/undefined values, you still can cache data either way, and execution order will still be non-deterministic to some extent, as await causes a suspended thread, but everything else outside connectedCallback is free to continue running while your data is being retrieved.

| improve this answer | |
  • If I understand collectly, when the connectedCallback is declared as async then the processing within the connectedCallback will itself be async so this won't actually delay the LWC infrastructure that itself called the connectedCallback. It does strike me that this then means other aspects, including rendering of the LWC could execute before the connectedCallback has itself completed its job. And thus other code in the component would still need to check that the static state is available, right? – Phil W Aug 5 at 13:15
  • @PhilW You can make an even stronger assertion than that; getters and other methods will execute before the connectedCallback finishes, so you do still need to check for null values and take nothing for granted. The only trivially useful point to using connectedCallback is you can assure the order of calls to the server, unlike wire methods, which are non-deterministic. – sfdcfox Aug 5 at 13:42
  • should you thus update your answer to clarify this point? Essentially the OP's assertion that using connectedCallback means you don't need to check is a fallacy. – Phil W Aug 5 at 15:46
  • @PhilW Good point. Updated. – sfdcfox Aug 5 at 16:05
  • @sfdcfox just a FYI: I believe your initial example of await in parallel is against best practices according to the MDN web docs: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. It is recommended to use Promise.all or Promise.allSettled instead. – voluminat0 Sep 17 at 9:50

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.