In Salesforce LWC (Lightning Web Component), we need to call Apex to access and manipulate data on the Salesforce backend, performing complex business logic operations that cannot be handled solely within the LWC.
To call an Apex method from LWC in Salesforce, we can use the wire property or the wire function, or call it imperatively.
In this Salesforce tutorial, we will learn how to call Apex from Lightning Web Components (LWC) using the wire and imperative methods.
Call Apex From Lightning Web Components (LWC)
Below, I will explain how to call an Apex class and its methods from Lightning web components to access their functionality.
Call Apex Using @wire Decorator in LWC
In the steps below, we will call an Apex method from Lightning Web Components (LWC) using the @wire function.
First, we will create an Apex class that contains the method that we will call from LWC. The class method must be static, either global or public, and annotated with @AuraEnabled.
For example, we have a class method that fetches the account record; it will look like this.
public with sharing class AccountController {
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts() {
return [SELECT Id, Name, Industry FROM Account LIMIT 10];
}
}Using the @AuraEnabled(cacheable=true) allows LWC to call this method and cache the response.
In this step, we will navigate to the LWC component’s JS file and call the Apex method. After navigating to the JS file, make the changes listed below.
After creating the apex class, we will import it into the JavaScript file using the code below.
import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/AccountController.getAccounts';
export default class AccountList extends LightningElement {
accounts;
error;
@wire(getAccounts)
wiredAccounts({ data, error }) {
if (data) {
this.accounts = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.accounts = undefined;
}
}
handleKeyChange(event){
this.searchKey = event.target.value;
}
}In the code above, using @wire(getAccounts) will call the Apex method and automatically fetch data when the component loads.
“Earlier, we used to have the @track decorator to monitor the changes in the values of object and array properties. After the Salesforce Spring ’20 release, using the @track decorator in LWC is no longer required.”
To display the fetched account data, enter the code below in the HTML file.
<template>
<lightning-card title="Account List">
<template if:true={accounts}>
<lightning-datatable
key-field="Id"
data={accounts}
columns={columns}>
</lightning-datatable>
</template>
<template if:true={error}>
<p>{error}</p>
</template>
</lightning-card>
</template>We have used <lightning-datatable> in this HTML template to display the Account records data.
To define the columns for the lightning-datable, update the HTML file.
columns = [
{ label: 'Account Name', fieldName: 'Name' },
{ label: 'Industry', fieldName: 'Industry' }
];To make the LWC component accessible to the Lightning page layouts, enter the code below in the XML file inside the LightningComponentBundle.
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>To deploy this component on the Lightning page, navigate to the page, click on the settings icon, then select Edit Page.
In the Components section, go to Custom Components, then drag and drop the element into the page layout.
Now, according to the defined Apex method, you will see the List of fetched accounts in the LWC component.

This way, we can invoke Apex methods in Salesforce Lightning Web Components using the @wire function.
Call Apex Using the Imperative Method in LWC
In Salesforce, to call Apex methods in LWC instead of using the @wire method, we can call them imperatively by hardcoding the logic to invoke them.
For the imperative method, create another LWC component and execute the code below in the component’s .js file.
import { LightningElement, track } from 'lwc';
import getAccounts from '@salesforce/apex/AccountController.getAccounts';
export default class ImperativeApexCall extends LightningElement {
@track accounts;
@track error;
columns = [
{ label: 'Account Name', fieldName: 'Name' },
{label:'Account Id', fieldName: 'Id'}
];
handleClick() {
getAccounts()
.then(result => {
this.accounts = result;
this.error = undefined;
})
.catch(error => {
this.error = error;
this.accounts = undefined;
console.error('Error retrieving accounts:', error);
});
}
}Let’s understand the logic we defined in the JS file above to fetch the account data.
From the LWC, we have imported @track to track the account and errors, storing the list of fetched accounts and any errors that occurred.
The Columns array defines how the data table displays the account information for the Account Name and ID columns.
After this, we defined the event handler handleClick(), which calls the Apex method getAccounts. If the call is successful, it will display the fetched account data.
Now, enter the code below in the .html file.
<template>
<lightning-card title="Account List">
<div class="slds-m-around_medium">
<lightning-button label="Get Accounts" onclick={handleClick} class="slds-m-left_small"></lightning-button>
</div>
<template if:true={accounts}>
<lightning-datatable key-field="Id" data={accounts} columns={columns}></lightning-datatable>
</template>
<template if:true={error}>
<p>{error}</p>
</template>
</lightning-card>
</template>After this, we will make the component available to the Lightning page by adding the code below to the XML file within the LightningComponentBundle tag.
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>Now add the Lightning component to the page layout. To add the component, Open Lighting Page > Edit Page > drag and drop the custom LWC component to the page > Click Save.
Now you can see that the component has been added to the page layout, and when we click the button, it will call the Apex method via the defined event.

This way, we can call the Apex methods in LWC using the imperative method.
Difference Between @wire Decorator & Imperative Method to Call Apex
When we need to call Salesforce Apex methods in LWC, we can use both @wire-decorated methods and call them imperatively via events.
The decision to choose one depends on how you retrieve and handle data from Apex methods.
Calling Apex From @wire decorator
When we use the @wire method in LWC, it provides automatic data binding between the Lightning component and the result of an Apex method call.
It is typically used for read-only operations (e.g., fetching records) because it cannot be used for DML operations.
The @wire methods keep the data in the cache, and for this, we use the @AuraEnabled(cacheable=true) parameter in the apex class that we call via the @wire decorator.
When we use the @wire method in Apex, data changes are automatically reflected in the component’s rendering.
There are also cons to using the @wire method, such as limited control over when the data is retrieved and less flexibility for custom error handling or complex processing.
Calling Apex Methods Imperatively
When we call Apex class methods using the imperative method, we define the entire logic by hardcoding it, replacing the @wire method with manual event methods in JavaScript.
When we need more control over the fetched data and its customization, we should use the imperative method to call Apex.
This method is flexible in handling errors and in customizing data processing, making it suitable for scenarios where we fetch data on demand, such as on a button click.
The cons of using the imperative method are that it involves more manual coding to handle data caching and errors.
Conclusion
In this Salesforce tutorial, we learned about two approaches to calling Apex from Lightning Web Components (LWC): the wire method and the imperative method. In the steps above, we called the Apex method in the LWC component using both @wire and an imperative method.
Later, we discussed the differences between the @wire and imperative methods. We should use the @wire method when we simply need to fetch read-only data, and the imperative method when we need more control over data modification.
You may also like to read:
- Create and Deploy LWC Components in Salesforce
- Implement Data Table with Inline Editing in LWC
- Add Styling to a Salesforce Lightning Datatable in LWC
- Salesforce Lightning Datatable Sorting in LWC
- addError() Method in Salesforce Apex
I am Bijay Kumar, the founder of SalesforceFAQs.com. Having over 10 years of experience working in salesforce technologies for clients across the world (Canada, Australia, United States, United Kingdom, New Zealand, etc.). I am a certified salesforce administrator and expert with experience in developing salesforce applications and projects. My goal is to make it easy for people to learn and use salesforce technologies by providing simple and easy-to-understand solutions. Check out the complete profile on About us.