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 notifyRecordUpdateAvailable(recordIds) to update the Lightning Data Service cache.

Let’s look at the apexImperativeMethod 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().

A Load Contacts button with a list of contacts underneath.

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.

The template uses lwc:if to render the list of contacts. It also uses for:each to iterate over the contacts.

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.

Enter characters in a seach field and click Search to return a list of contacts.

To call a method with an object parameter, check out the apexImperativeMethodWithComplexParams component in the lwc-recipes repo.

When you pass values such as record data from LWC to Apex, use JavaScript objects or arrays. Map values are not serialized when passed to Apex methods.

Using maps isn’t supported for both imperative and wired Apex calls. The improper use of maps, such as with map[key] = val, allowed the data to be passed with Lightning Web Security (LWS) disabled. However, this usage no longer works when LWS is enabled. Furthermore, map.set(key, val) isn’t supported for passing values to Apex.

You can use a JavaScript object like this.

When you call Apex imperatively, use the try/catch block to handle errors.

Alternatively, you can also use the syntax of a promise like this.

The Apex method calls the then or catch block depending if there's an error. Calling the then and catch blocks happens asynchronously, so you can't put the whole getContactList() method within a try-catch block.

In this case, the catch block handle errors from both the Apex method and the then block. If the getContactList() Apex method throws an exception, you can handle it in the catch block. If the Apex method runs successfully, your code in the then runs next. And if there's an error in the then block, you can also handle it in the catch block. See Handle Errors from Apex.

See Also