Salesforce Wire Adapters and LWC Lifecycle

Something that can catch your attention when debugging an LWC with an @wire, is that if you set a breakpoint just after it, the first time that this breakpoint stops, the data will be undefined. And yes, just the first time, because the code will go through this breakpoint again before you can manually interact with the LWC, and this time, the data will contain information.

My first thought when I first saw this behaviour –ย ย “Hold on, what?!” But I obviously did not understand the wire adapters, but also the LWC lifecycle. Until now!

The Lightning Data Service (LDS) wire adapters are endpoints that can be invoked in a specific way (using @wire) to create a reactive service to read data… But if you want to dig into this, I’ll add some links for you at the end of this post ๐Ÿ˜‰

Now that we have defined what a wire adapter is, let’s have a look at how it fits in the LWC lifecycle. I will explain this with an easy code example.

import { LightningElement, wire, api } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/MyCustomObject__c.Name';

export default class DoTheThing extends LightningElement {
    recordId = 'a073i0000049kNMAAY';

    @wire(getRecord, {recordId:'$recordId', fields: [NAME_FIELD]})
    myWiredRecord ({data, error}){
        debugger;
        if(data){
            debugger;
            //codigo
        }
    }
}

I want you to pay attention at the lines with the debugger, so lines 10 and 12. Because the browser will not always will stop in both, but will stop depending on what the data contains.

In what apparently is the “first” run, the browser will stop only in line 10 debugger. This is because the data contain undefined at this point, and so, the if statement will evaluate to falseย forcing the browser do not follow this path. It will beย at the “second” run when the data will contain a value different to undefined.

Alright, we can observe a few things here:

  1. The first thing executed here is the constructor. At this point, properties are set, for example the recordId.
  2. Just after the constructor, and before any other LWC lifecycle event, the wire serviceย sends a default object like the following {data: undefined, error: undefined}.
    This default object is responsible at making the browser stop at line 10 debugger and showing undefined as the value for data.
  3. connectedCallback is executed, and after it, the @wire is called again. This timeย @wire consumes the values stored in recordId and [NAME_FIELD]. And so, data or error values will be modified and in case everything worked accordingly the line 12 debugger will force the browser to stop.

So, Our example lifecycle will be something like this:

  1. constructor
  2. Properties are set
  3. wire service sends a default objectย {data: undefined, error: undefined}
  4. Line 10 debugger
  5. connectedCallback
  6. wire service returns a new record, but this time the wire service is using theย infoย stored in recordId and [NAME_FIELD] and bringing thatย value from the cache or server
  7. Line 10ย debugger
  8. wire serviceย returnsย data
  9. Line 12ย debugger

I will finish by addingย that there are other events that can make the @wire react, besides the modification of the parameters. These are the record modification in the LDS cache or by forcing the wired property to be refreshed.

And if you want to learn more about wire adapters, the LDS and the LWC lifecycle, I recommend you to have a look at the following links.

 

Photo by Steve Johnson on Unsplash

Work with Desynit

Looking for exceptional, professional Salesforce support?

Our independent tech team has been servicing enterprise clients for over 15 years from our HQ in Bristol, UK. Let’s see how we can work together and get the most out of your Salesforce implementation.