Monday, December 19, 2022

Wire Service in Lightning Web Component LWC

wire service

Lightning web components(LWC) use a reactive wire service, which is built on Lightning Data Service. Components use @wire in their JavaScript class to read data from one of the wire adapters in the lightning/ui*Api modules and also to call the apex controller server-side methods using wire services.

Reactive wire service supports reactive variables, which are prefixed with $. If a reactive variable changes, the wire service provisions(requests) new data.

wire service syntax

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/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.

@wire can be used as:

  • To a property
  • As a function

Wire a property : Here, the wire service either provides you with the list of account to the wiredAccounts.data property, or returns an error to the wiredAccounts.error property.

//below code will wire list of Account data  
@wire(getAccounts) wiredAccounts;

Wire a function :
Wire a function if you want to operate on the returned data. If a function is decorated with @wire, the results are returned in an object with a data property or an error property.

@track lstaccounts;   @track error;   
//below code will be used as a function
@wire(getAccounts) wiredAccounts ({ error, data }) {
       if (data) {
           this.lstaccounts = data; 
      } else if (error) { 
          this.error = error;  
     }   }

Import references to salesforce Object and fields

1. To import a reference to an object, use this syntax.

import objectName from '@salesforce/schema/object';
Ex:
import PROPERTY_OBJECT from '@salesforce/schema/Property__c';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';

2. To import a reference to a field, use this syntax.

import FIELD_NAME from '@salesforce/schema/object.field';

Ex:

import POSITION_LEVEL_FIELD from '@salesforce/schema/Property__c.Name';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';

3. To import a reference to a field via a relationship, use this syntax.

import SPANNING_FIELD_NAME from '@salesforce/schema/object.relationship.field';

Ex:

import ACCOUNT_OWNER_NAME_FIELD from '@salesforce/schema/Account.Owner.Name';

Decorate a Property with @wire

  • Wiring a property with @wire is useful when you want to consume the data or error.
  • If the property decorated with @wire is used as an attribute in the template and its value changes,
  • the wire service provisions(requests) the data and triggers the component to rerender.

Ex:

import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';

export default class Record extends LightningElement {
    @api recordId;

    @wire(getRecord, { recordId: '$recordId', fields: ['Opportunity.Name'] })
    record;
}

Practical Example
ContactExp.apxc

public with sharing class ContactExp {
     @AuraEnabled(cacheable=true)
     public static List<contact> getContactList() {
        List<contact> conList= [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 10];
         return conList;
     }
 }

contactList.html
<template>
    <lightning-card title="Decorate a Property with @wire" icon-name="custom:custom63">
        <div class="slds-m-around_medium">
            <template if:true={contacts.data}>
                <template for:each={contacts.data} for:item="contact">
                    <p key={contact.Id}>{contact.Name}</p>
                </template>
            </template>
        </div>
    </lightning-card>
</template>

contactList.js
import { LightningElement, wire } from 'lwc';
 import getContactList from '@salesforce/apex/ContactExp.getContactList';
 export default class contactList extends LightningElement {
     @wire(getContactList) 
     contacts;
 }
Output:

Decorate a Function with @wire

  • Wiring a function is useful to perform logic whenever new data is provided or when an error occurs. 
  • The function is invoked whenever a value is available, which can be before or after the component is connected or rendered.

Ex:

import { LightningElement, api, track, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';

export default class WireFunction extends LightningElement {
    @api recordId;
    @track record;
    @track error;

    @wire(getRecord, { recordId: '$recordId', fields: ['Opportunity.Name'] })
    wiredAccount({ error, data }) {
        if (data) {
            this.record = data;
        } else if (error) {
            this.error = error;
        }
    }
}
Practical Example
This component wires an Apex method call to a function. Because the results are coming to a function, the JavaScript can work on the results.

ContactExp.apxc

public with sharing class ContactExp {
     @AuraEnabled(cacheable=true)
     public static List<contact> getContactList() {
        List<contact> conList= [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 10];
         return conList;
     }
 }

contactshow.html

<template>
    <lightning-card title=”Decorate a Function with @wire” icon-name=”custom:custom63″> 
       <div class=”slds-m-around_medium”>  
          <template if:true={contacts}>  
              <template for:each={contacts} for:item=”contact”> 
                   <p key={contact.Id}>{contact.Name}</p>                
</template>           
  </template>            
<template if:true={error}> 
               <c-error-Exp errors={error}></c-error-Exp>
            </template>
        </div>
    </lightning-card>
</template>

contactshow.js

import { LightningElement, wire } from ‘lwc’;
import getContactList from ‘@salesforce/apex/ContactExp.getContactList’;

export default class contactDisplay extends LightningElement {
contacts;
error;
    @wire(getContactList)
wiredContacts({ error, data }) {
if (data) {
            console.log(‘data: ‘, data);
            this.contacts = data;
            console.log(‘this.contacts: ‘, this.contacts);
            this.error = undefined;
|            console.log(‘this.error: ‘, this.error);
        } else if (error) { 
           console.log(‘error ‘, error);
            this.error = error; 
           console.log(‘this.error: ‘, this.error); 
           this.contacts = undefined;
            console.log(‘this.contacts : ‘, this.contacts);
        }
    }}

errorExp.html

<template>
    <template if:true={errors}>
      status: {errors.status}<br />
      statusText: {errors.statusText}<br />
      <template for:each={errors.body} for:item=”error”>
        statusText: {error.message}  
     </template>
    </template> 
 </template>

errorExp.js

import { LightningElement,api } from ‘lwc’;
export default class ErrorPanel extends LightningElement {

    @api errors;
}

Output:

Related

No comments:

Post a Comment

Understanding Wire vs Imperative Apex Method Calls in Salesforce Lightning Web Components (LWC)

Understanding Wire vs Imperative Apex Method Calls in Salesforce Lightning Web Components (LWC) Introduction: Salesforce Lightning Web ...