Wire Service In Lightning Web Components
The wire service provisions an immutable stream of data to the component. Each value in the stream is a newer version of the value that precedes it.
We call the wire service reactive in part because it supports reactive variables, which are prefixed with $
. If a reactive variable changes, the wire service provisions new data. We say “provisions” instead of “requests” or “fetches” because if the data exists in the client cache, a network request may not be involved.
Wire Service Syntax:
Import a wire adapter using named import syntax. Decorate a property or function with @wire and specify the wire adapter.
import { adapterId } from 'adapterModule';
@wire(adapterId, adapterConfig)
propertyOrFunction;
- adapterId (Identifier)—The identifier of the wire adapter.
- adapterModule (String)—The identifier of the module that contains the wire adapter function, in the format namespace/moduleName. Look at the format! To import a module in JavaScript, use lightning/uiApi instead of lightning-ui--api.
- adapterConfig (Object)—A configuration object specific to the wire adapter. Configuration object property values can be either strings or references to objects and fields imported from @salesforce/schema. Properties in the adapterConfig object can’t be undefined. If a property is undefined, the wire service doesn’t provision data. Don’t update a wire adapter configuration object property in renderedCallback() as it can result in an infinite loop.
- propertyOrFunction—A private property or function that receives the stream of data from the wire service. If a property is decorated with @wire, the results are returned to the property’s data property or error property. If a function is decorated with @wire, the results are returned in an object with a data property and an error property.
Decorate a Property With @wire:
We would be updating the decoratorLwc component which we created in the previous part – LWC Decorators
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';
export default class DecoratorLwc extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: [ACCOUNT_NAME_FIELD] })
record;
get name() {
return this.record.data.fields.Name.value;
}
}
Let’s understand the above code line by line:
import { LightningElement, api, wire } from 'lwc';
At Line 1 we import the decorator references. Notice that we have imported both api & wire decorator references.
import { getRecord } from 'lightning/uiRecordApi';
At Line 2 we have imported the adapterId – getRecord from the adopterModule – lightning/uiRecordApi
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';
At line 3 we are importing the references to Account Name Field. In the same way, we can import the reference for other standard object or Custom object.
There is a significance to importing the references to the object or fields in this manner. Salesforce verifies that the objects and fields exist, prevents objects and fields from being deleted, and cascades any renamed objects and fields into your component’s source code.
It also ensures that dependent objects and fields are included in change sets and packages. Importing references to objects and fields ensures that your code works, even when object and field names change.
@api recordId;
At line 6 we have created a property recordId and decorated it with @api. This ensures it is public property and it will be populated by the Salesforce framework with the respective record id if added to a record Detail Page.
@wire(getRecord, { recordId: '$recordId', fields: [ACCOUNT_NAME_FIELD] })
record;
At line 8 we have decorated the record property with @wire decorator by specifying the adapterId which is getRecord and by providing adapterConfig which is { recordId: ‘$recordId’, fields: [ACCOUNT_NAME_FIELD] }
There are many more wire adapters available to use. Feel free to visit the official docs to explore all the available wire adapters.
The $ prefix in the configuration object makes the property reactive. If the property’s value changes, new data is provisioned and the component rerenders.
Use the $ prefix for top-level values in the configuration object. Nesting the $ prefix such as in an array like [‘$accountIds’] makes it a literal string, which is not dynamic or reactive.
The object supplied to the property (in this example, record) has this shape.
data (Any type)—The value supplied by the adapter.
error (Error)—An error if the adapter wasn’t able to supply the requested data or if the adapter wasn’t found. Otherwise, this property is undefined.
The property is assigned a default value after component construction and before any other lifecycle event. The default value is an object with data and error properties of undefined.
Therefore, you can access the property’s value in any function, including functions used by the template or used as part of the component’s lifecycle.
Now let’s add the below HTML code to the decoratorLWC HTML file:
<template>
<lightning-card title="DecoratorLwc" >
<template if:true={record.data}>
<p class="slds-p-horizontal_small">
Account Name From Wire Service - {name}
</p>
</template>
</lightning-card>
</template>
Add the decoratorLwc component to Account’s record page. You would be seeing an output as below:
Decorate a Function With @wire:
Wiring a function is useful to perform logic whenever new data is provided or when an error occurs. The wire service provisions the function of an object with error and data properties, just like a wired property.
The function is invoked whenever a value is available, which can be before or after the component is connected or rendered.
Let’s update the decoratorLwc component with the following code:
import { LightningElement, api, track, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';
export default class DecoratorLwc extends LightningElement {
@api recordId;
@track record;
@track error;
@wire(getRecord, { recordId: '$recordId', fields: [ACCOUNT_NAME_FIELD] })
wiredAccount({ error, data }) {
if (data) {
this.record = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.record = undefined;
}
}
get name() {
return this.record.fields.Name.value;
}
}
<template>
<lightning-card title="DecoratorLwc" >
<template if:true={record}>
<p class="slds-p-horizontal_small">
Account Name From Wire Service - {name}
</p>
</template>
</lightning-card>
</template>
Using and decorating @wire with a function is similar to using it with a property. Please note that the function wiredAccount({ error, data }) is invoked whenever a value is available.
We can also wire Apex Methods which we have covered in a separate post. Please go through them over here – Wire Apex Methods To Lightning Web Components
Thank you for visiting SalesforceBlue.com
If you have any queries feel free to write down a comment below 🙂