Call Apex Methods Imperatively
To control when the method invocation occurs (for example, in response to clicking a
button), call the method imperatively. When you call a method imperatively, you receive only
a single response. Compare this behavior with @wire
, which delegates control to the framework and results in a stream of values
being provisioned.
In the following scenarios, you must call an Apex method imperatively as opposed to
using @wire
.
- To call a method that isn’t annotated with
cacheable=true
, which includes any method that inserts, updates, or deletes data. - To control when the invocation occurs.
- To work with objects that aren’t supported by User Interface API, like Task and Event.
- To call a method from an ES6 module that doesn’t extend
LightningElement
If an Apex method is marked with @AuraEnabled(cacheable=true)
, a client-side Lightning Data Service
cache is checked before issuing the network call to invoke the Apex method on the
server. However, Lightning Data Service doesn’t manage data provisioned by Apex.
Therefore, to refresh stale data, invoke the Apex method and then call getRecordNotifyChange()
to update
the Lightning Data Service cache.
Call an Apex Method
Let’s look at a sample component from the lwc-recipes
repo that uses the same getContactList
class as our previous examples. Instead of wiring it, when a user clicks a button,
the component calls getContactList()
.
The imported function returns a promise. This code provides a one-time resolution
given a set of parameters, whereas @wire(apexMethod)
provides a stream of values and supports dynamic parameters.
// apexImperativeMethod.js
import { LightningElement, track } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class ApexImperativeMethod extends LightningElement {
@track contacts;
@track error;
handleLoad() {
getContactList()
.then(result => {
this.contacts = result;
})
.catch(error => {
this.error = error;
});
}
}
public with sharing class ContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> getContactList() {
return [
SELECT Id, Name, Title, Phone, Email, Picture__c
FROM Contact
WHERE Picture__c != NULL
WITH SECURITY_ENFORCED
LIMIT 10
];
}
}
Like our other examples, the template uses if:true
to render the list of contacts or an error panel. It also uses for:each
to iterate over the contacts.
<!-- apexImperativeMethod.html -->
<template>
<lightning-card title="ApexImperativeMethod" icon-name="custom:custom63">
<div class="slds-m-around_medium">
<p class="slds-m-bottom_small">
<lightning-button label="Load Contacts" onclick={handleLoad}></lightning-button>
</p>
<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-panel errors={error}></c-error-panel>
</template>
</div>
</lightning-card>
</template>
Call an Apex Method with Parameters
Pass parameters values to an Apex method in an object whose properties match the parameters of the Apex method. For example, if the Apex method takes a string parameter, don’t pass a string directly. Instead, pass an object that contains a property whose value is a string.
// apexImperativeMethodWithParams.js
import { LightningElement } from 'lwc';
import findContacts from '@salesforce/apex/ContactController.findContacts';
export default class ApexImperativeMethodWithParams extends LightningElement {
searchKey = '';
contacts;
error;
handleKeyChange(event) {
this.searchKey = event.target.value;
}
handleSearch() {
findContacts({ searchKey: this.searchKey })
.then((result) => {
this.contacts = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.contacts = undefined;
});
}
}
public with sharing class ContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> findContacts(String searchKey) {
String key = '%' + searchKey + '%';
return [
SELECT Id, Name, Title, Phone, Email, Picture__c
FROM Contact
WHERE Name LIKE :key AND Picture__c != NULL
WITH SECURITY_ENFORCED
LIMIT 10
];
}
}
No comments:
Post a Comment