Lightning Web Components:@Wire and Imperative Apex Server Calls in LWC

In this post we are going to discuss about how we can make server call to the apex:method from our lightning web component. There are two ways for doing so :

First is using @wire to wire a property or a function in JavaScript to apex method and second is calling an apex method imperatively.

Using @wire to wire a property or function

  1. Make the apex method @AuraEnabled(cacheable =true)

2. Import the apex method into javascript file of your component using:

  import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod’; 

3. Wire the imported method to a property or function which will receive stream of data from the wire service.


@wire(apexMethod, {apexMethodParams})
propertyOrFunction;

Lets understand this better with implementation.

We will create a component name “getcontactComp”. In these component we will fetch the list of contacts from salesforce and display using for:each iteration and lightning card.

For fetchning the records from contact , we will write an auraenabled method similar to way in which we write for aura components.

Using @wire to wire a property.

ContactController.cls

public class ContactController {
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContacList(){
        List<Contact> conList = [select id,lastname from contact limit 6];
        return conList;
    }
}

getcontactComp.cmp

<template>
 
        <template for:each={conList} for:item="contact">
            <lightning-card key = {contact.LastName} icon-name="standard:contact">
                <p>{contact.LastName}</p>
            </lightning-card>
        </template>
</template>

getcontactComp.js

import { LightningElement,track,wire,api} from 'lwc';
import getContacList from '@salesforce/apex/ContactController.getContacList';
export default class GetcontactComp extends LightningElement {

    @track conList ;
    @wire (getContacList) conList;
   
}

Using @wire to wire a function.

getcontactComp.js

 
import { LightningElement,track,wire,api} from 'lwc';
import getContacList from '@salesforce/apex/ContactController.getContacList';
export default class GetcontactComp extends LightningElement {

    @track conList ;
   @wire (getContacList)
    contactList({error,data}){
        if(error){
            console.log('error is#'+error);

        }
        else if(data){
            console.log('contact data#'+data);
            this.conList = data;
        }

    }
 
   
}

We will include component insde aura application and load the app. You will notice that contact details are displayed in inside lightning cards.

@wire with dynamic paramters

Call to apex method using @wire is executed at the time component loads. But suppose we want to make server call when a particular parameter changes.

So for that we can @wire an apex method with a dynamic parameter. We need to pass a parameter with “$” appended to it while making call to apex method. So, once the value of this property changes, call to apex is made at that time.

We will update the above components, and include a boolean property “showContacts”.

getcontactComp.html

<template>
    <template if:true = {showContacts}>
  
        <template for:each={conList} for:item="contact">
            <lightning-card key = {contact.LastName} icon-name="standard:contact">
                <p>{contact.LastName}</p>
            </lightning-card>
        </template>
  
    </template>
    <br>
    <lightning-input type="checkbox" label="Show Contacts" checked={showContacts} onchange={handleFlag}></lightning-input>

</template>

getcontactComp.js

import { LightningElement,track,wire,api} from 'lwc';
import getContacList from '@salesforce/apex/ContactController.getContacList';
export default class GetcontactComp extends LightningElement {

    @track conList ;
    @track showContacts = false;

    handleFlag(event){
        this.showContacts = event.target.checked;

    }
@wire (getContacList,{flag : '$showContacts'})
    contactList({error,data}){
        if(error){
            console.log('error is#'+error);

        }
        else if(data){
            console.log('contact data#'+data);
            this.conList = data;
        }

    } 
}

ContactController.cls

public class ContactController {
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContacList(Boolean flag){
        List<Contact> conList = [select id,lastname from contact limit 6];
        return conList;
    }
}

Initially its value is kept false, so no contact list is displayed.

Once we click on “Show Contacts” button, this paramter is made true and since its value changes and it is used with @wire apex call, the @wire call is made which fetches the contact list and displays inside our component.

Imperative Apex Server Calls in LWC

Suppose you don’t want to call to an apex method when component gets loaded. You want to make call to the an apex method on click of a button or on certain logic, so for that we can make call to apex method in imperative way.

We will update our “GetcontactComp”. We will add a button “Get Contacts” to HTML file and bind it to getcontacts method in javascript file.

We will make call to apex method. Using then and catch you can get the result into your local variables as imperative call returns the promises so you have to resolve your promises into a result or error objects.

getcontactComp.html

<template> 
        <template for:each={conList} for:item="contact">
            <lightning-card key = {contact.LastName} icon-name="standard:contact">
                <p>{contact.LastName}</p>
            </lightning-card>
        </template>

   <lightning-button label="Get Contacts" onclick={getContacts}></lightning-button>
    <br>
</template>

getcontactComp.js

/* eslint-disable no-console */
import { LightningElement,track,wire,api} from 'lwc';
import getContacList from '@salesforce/apex/ContactController.getContacList';
export default class GetcontactComp extends LightningElement {

    @track conList ;
  // Using imperative call to server 
  getContacts(){
    getContacList().then(result => {
        console.log('result#'+result);
        this.conList = result;
        
    })
    .catch(error => {
        console.log('error#'+error);
       
    })
}
  
}

We will deploy the changes to salesforce org and reload the application. You can see “Get Contacts” button on screen.

Now if you click on button list of contacts will be displayed.

Thus, we can make call to apex class using @wire or imperatively based on our requirement.

So , we will wrap up this post here . Stay tuned for next posts !

Advertisement