-
Notifications
You must be signed in to change notification settings - Fork 10
lwc 301 lds advanced
A couple of concepts for more advanced usage of LDS Adapters:
- Wire infrastructure
- Multi wire flow control
- Network boxcar-ing
Wires are promises under the hood. During the lifecycle of an LWC, wires are called between constructor
and connectedCallback
(AFAIK, this is undocumented - I sourced this from some folks at SFDC).
However, the design of a wire call is very interesting. It will always call server twice:
- First is usually
undefined
since it's variable you've bound with the magic syntax$myVar
will likely be unavailable betweenconstructor
andconnectedCallback
. - Second call is when the wire framework detects a change in the magic syntax bound prop.
Concrete example: When using the getRecord
adapter which accepts the recordId
variable, it will call one time with undefined
and the second time when the @api recordId
interface passes the actual recordId from the flexipage container, through the api of the LWC, into the bound property.
This "re-assignment" of the bound variable is what triggers a wire call and triggers its reactivity and cacheable=true
infrastructure.
Note: Forward Looking Statement, there is some variant of promise.all() in the works for wires. Or, some other variant which should grant a little more predictability here. until then, this is the workaround.
Once you understand how (intentional) variable assignment triggers the actual desired wire call, you can then manipulate this to your advantage.
Here is an example:
// Goes first
@wire(getObjectInfo, { objectApiName: '$_objectApiName' })
currentObjectWire({ error, data }) {
...
this._getRecordFields = ['MyField__c']
...
}
// Goes second, since not all bound variables are truthy on load - the callback of the first will get this to fully resolve.
@wire(getRecord, { recordId: '$recordId', fields: '$_getRecordFields' })
currentRecordWire({ error, data }) {
...
}
This originates from the aura infrastructure and has (I believe) carried over in some way in LWC-land. However, this isn't documented clearly so this is mostly speculative.
For prior art in Aura, please see here:
For LWC consider the following sources:
-
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/data_table_inline_edit
- Ctrl+F
Enable Inline Editing for Multiple Rows
, excerpt below:
- Ctrl+F
const promises = recordInputs.map((recordInput) => updateRecord(recordInput));
Promise.all(promises)
.then((contacts) => {
...
})
.catch((error) => {
...
});
or using async await
await Promise.all(
recordInputs.map(async recordInput => {
try {
const successResult = await updateRecord(recordInput);
...
} catch (error) {
...
}
})
);
Anecdotally, I've found that LDS adapters that allow for DML (updateRecord
, deleteRecord
) are boxcar-ed by the framework so it's not 1 network request per record.