Understand the Wire Service
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.
Objects passed to a component are read-only. To mutate the data, a component should make a shallow copy of the objects it wants to mutate. It’s important to understand this concept when working with data. See Data Flow.
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.
The wire service delegates control flow to the Lightning Web Components engine. Delegating control is great for read operations, but it isn’t great for create, update, and delete operations. As a developer, you want complete control over operations that change data. That’s why you perform create, update, and delete operations with a JavaScript API instead of with the wire service.
Import a wire adapter using named import syntax. Decorate a property or function with @wire
and specify the wire adapter. Each wire adapter defines a data type.
The wire service provisions an immutable stream of data. The data is not guaranteed to be the same, even when the adapterConfig object content is the same.
adapterId
(Identifier)—The identifier of the wire adapter.adapterModule
(String)—The identifier of the module that contains the wire adapter function, in the formatnamespace/moduleName
. To import a module in JavaScript, use the formatlightning/ui*Api
instead oflightning-ui-*-api
. For example,lightning/uiRecordApi
.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 inrenderedCallback()
as it can result in an infinite loop.
Read the data that's returned by the wire adapter using a property or function.
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’sdata
property orerror
property. - If a function is decorated with
@wire
, the results are returned in an object with adata
property and anerror
property.
The data
property and the error
property are hardcoded values in the API. You must use these values for most wire adapters. The GraphQL wire adapter uses errors
instead of error
, which maintains compatibility with the GraphQL response specification.
When you use a wire adapter in a lightning/ui*Api
module, we strongly recommend importing references to objects and fields. 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.
To follow along with some code samples, see the lwc-recipes repo. Look for components whose names start with wire
.
If a component isn’t aware of which object it’s using, use strings instead of imported references. Use getObjectInfo
to return the object’s fields. All wire adapters in the lightning/ui*Api
modules respect object CRUD rules, field-level security, and sharing. If a user doesn’t have access to a field, it isn’t included in the response.
Currently, name changes don’t cascade thoroughly into source code for approximately two hours. For a component used in App Builder, this timing is also important if the component’s meta.xml file uses <objects>
to constrain the object home or record home.
To access object and field API names, use an import
statement. All object and field imports come from @salesforce/schema
scoped packages.
To import a reference to an object, use this syntax.
To import a reference to a field, use this syntax.
To import a reference to a field via a relationship, use this syntax. You can use relationship fields to traverse to parent objects and fields. You can specify up to three relationship fields, which results in four objects and the field being referenced. For example, Opportunity.Account.CreatedBy.LastModifiedById
returns 4 levels of spanning fields.
For objects, we use the naming convention OBJECTNAME_OBJECT
. For fields, we use the naming convention FIELDNAME_FIELD
. We use these naming conventions to make code easier to understand. They’re guidelines, not rules.
This code imports the Account.Name
field and uses it in a wire adapter’s configuration object.
This code is almost identical, but it uses a string to identify the Account.Name
field. This code doesn’t get the benefits that you get from importing a reference to the field.
Name fields, address fields, and geolocation fields are compound fields. A compound field is accessible as a single, structured field, or as individual constituent fields. The value contained in the compound field and the values in the constituent fields both map to the same data stored in Salesforce.
In a read operation, you can import a reference to a compound field or to its constituent fields. For example, in a read operation, you can use Contact.Name
, which is a compound field.
For create and update operations on compound fields using lightning/ui*Api
functions like updateRecord(recordInput, clientOptions)
, you must import the constituent fields. For example, import Contact.FirstName
and Contact.LastName
instead of Contact.Name
. Remember to include all the required constituent fields. For example, to create a contact, the LastName
field is required.
A compound address field is supported through its constituent fields. To access an address field, use its constituent fields with string syntax.
A compound geolocation field is supported through its constituent fields. To access a geolocation field, use its constituent fields with string syntax.
The Build a Bear-Tracking App with Lightning Web Components Trailhead project uses the compound geolocation field and transforms the latitude and longitude data into map markers.
Salesforce supports many object or field suffixes to represent different types of data. Lightning Web Components supports the import of references to standard objects, as well as the import of references to custom objects (__c
) only. For example:
Consider these workarounds for importing references to some other object or field suffixes.
- Person Accounts
A
__pc
field represents a person account, which stores information about an individual person by combining certain account and contact fields into a single record. Every custom field created in the Contact object is available for person accounts in the Account object using the__pc
suffix, but this syntax doesn't work in animport
statement.Instead of importing a
__pc
field from the Account object, import the custom field from the Contact object to get the benefits of referential integrity.Later in the JavaScript file, you can directly access the
Account.myCustomField__pc
field that referencesContact.myCustomField__c
. For example:- External Objects
An
__x
suffix represents an external custom object, which is similar to a custom object, except that it maps to data that’s stored outside your Salesforce org.To retrieve data from an external custom object, call a method in an Apex class that gets the data with a SOQL query.
Knowledge__kav
cannot be imported in a custom component. To use a field on Knowledge__kav
with a wire adapter, pass in the field directly using the fields: ['Knowledge__kav.Title']
syntax.
In the wire adapter’s configuration object, prefix a value with $
to reference a property of the component instance. The $
prefix tells the wire service to treat it as a property of the class and evaluate it as this.propertyName
. The property is 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.
In this example, $recordId
is dynamic and reactive.
A value without a $
, like the value of the fields
property in a previous example, is a static value, [AccountNameField]
.
You can designate these types of configuration object properties as dynamic and reactive.
- Private properties
- Properties defined by a getter-setter pair
- Properties decorated with
@api
Wiring a property is useful when you want to consume the data or error as-is.
If the property decorated with @wire
is used as an attribute in the template and its value changes, the wire service provisions the data and triggers the component to rerender. The property is private, but reactive.
This code applies @wire
to the record
property.
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.
Since you pass in an object to an @wire
function, the parameter order is irrelevant. You can use either data, error
or error, data
. The order matters only when you are destructuring arrays.
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 isundefined
.
When data becomes available from the wire adapter, it’s set in the data
property (error
remains undefined
). When newer versions of the data are available, data
is updated.
If an error occurs in the adapter, for example when retrieving the data, error
is populated with an error object (data
is set to undefined
).
You can use one @wire
output as another @wire
input. For example, you could use $record.data.fieldName
as an input to another wire adapter.
Wiring a function is useful to perform logic whenever new data is provided or when an error occurs. The wire service provisions the function 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.
A wire adapter is evaluated only when its configuration is complete, which occurs when you define a value for all dynamic parameters for the call. For example, this can take longer if you use a parent component that retrieves data using a wire and then passes on the result to a child component, which in turn uses the result to retrieve data from another wire.
When the component is initialized, it fires the constructor()
. Assuming the configuration on the wire adapter is complete, a Lightning Data Service (LDS) wire provisions an empty object containing the data
and error
properties, each with an undefined
default value.
Next, the connectedCallback()
, render()
, and renderedCallback()
lifecycle hooks are fired in that order.
When data becomes available from the wire adapter, it’s set in the data
property while error
remains undefined
. When newer versions of the data are available, LDS emits a value on the wire. If the component uses the data to change the content of its template, the render()
and renderedCallback()
hooks are fired again.
An LDS wire can emit data multiple times without the component changing its configuration. LDS controls these emits, and they aren't related to the LWC component lifecycle.
Consider these guidelines when using a wire adapter.
- Apex wire adapters are also LDS-based. Wire adapters listed in the Reference section are LDS-based unless otherwise specified.
- Wire adapter calls are asynchronous unless data is cached. Therefore, the order of response and promise resolution are not sequential.
- Data can be returned at any time. Although LDS tries to return the data as soon as possible, multiple layers of caching involved in your request can impact how quickly you get the data. If data is already available in LDS cache, it's returned without a network call. If data is not in the cache, then the wire evaluation results in a network call.
- Don't depend on receiving data from a wire adapter at any specific point in your component lifecycle. The wire can receive data as often as necessary and at any time. Use the wire adapter as a way to retrieve the data you need. The framework determines when, how, how often, and from where to get that data.
- If you asynchronously change a record using an Apex trigger or an auto-launched flow, the wire adapter won't be re-evaluated.
See Also
- Lightning Data Service
- lightning/ui*Api Wire Adapters and Functions
- @salesforce Modules
- Lifecycle Hooks