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 format namespace/moduleName. Look at the format! To import a module in JavaScript, use lightning/ui*Api 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.

    The data property and the error property are hardcoded values in the API. You must use these values.

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 an import 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 references Contact.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.

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.

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.

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.

See Also