In the fast-evolving world of Salesforce development, the harmonious interplay between frontend (Lightning Web Components) and backend (Apex) is pivotal. Every Salesforce developer, whether novice or expert, stands to benefit from mastering the integration of these two powerful tools.
From this blog, you will:
- Understand the fundamentals of Lightning Web Components and the Apex programming language.
- Learn the two primary ways to call Apex methods from LWC: using wire services and calling methods imperatively.
Let’s get started!
What is LWC?
Lightning Web Components, commonly referred to as LWC, represent Salesforce’s step into the modern web development era. They are a lightweight framework introduced by Salesforce for building fast, efficient, and reusable web components on the Salesforce Lightning Platform.
Why does LWC matter?
As web development evolves, it’s vital for platforms to adapt and adopt the best of the web. LWC allows Salesforce developers to create components with a modern development approach, ensuring the applications they build are robust, maintainable, and high-performing.
In essence, Lightning Web Components are Salesforce’s answer to the modern web, providing developers with a powerful toolset to craft efficient and dynamic web apps on the Salesforce platform.
What is Apex?
Apex is Salesforce’s proprietary programming language, tailored for building business logic on the Salesforce platform. It’s an object-oriented language, with syntax that closely resembles Java, enabling developers to execute flow and transaction control statements on the Salesforce servers in conjunction with calls to the Salesforce API.
How Does Apex Work with LWC?
- Backend Support: While LWC handles the frontend user interface, Apex provides the backend support, allowing components to interact with Salesforce data and perform complex operations.
- Invoking Apex Methods: From a Lightning Web Component, developers can either “wire” an Apex method to a property or function or call it imperatively based on user interactions. This bridges the gap between front-end interactions and server-side logic.
- Reactivity and Data Binding: When an LWC component requires data, it can leverage Apex to fetch this data. With reactive properties in LWC, any change in the data layer can be automatically reflected in the UI.
- Data Security: By using Apex with LWC, developers inherently benefit from Salesforce’s robust data access and security model. Only the data a user has permission for is accessible, ensuring data integrity and security.
- Error Handling: In conjunction with LWC, Apex provides detailed error messages that can be caught and handled gracefully in the UI, enhancing user experience.
Calling an Apex Method Using Wire Services in LWC
The wire service in LWC provides a streamlined way to retrieve data or perform an action without requiring Apex code. With the wire service, you can wire a property or function to a service, ensuring it automatically receives new data when the source updates.
1. Setting Up the Apex Method
Before you can use the wire service, your Apex method must be set up correctly. This typically involves annotating the method with @AuraEnabled and setting cacheable=true for read-only operations.
For example, consider an Apex method that fetches a list of contacts:
public with sharing class ContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> getContacts() {
return [SELECT Id, Name, Email FROM Contact LIMIT 10];
}
}
2. Wiring to an Apex Method
In your LWC, you’d use the @wire decorator to wire a property or function to the Apex method.
First, import the Apex method:
import getContacts from ‘@salesforce/apex/ContactController.getContacts’;
Next, use the @wire decorator to bind the method to a property:
@wire(getContacts) contacts;
The contacts property will now have the data structure:
{
data: [/* array of contacts */],
error: {/* error information */}
}
You can easily access the data or error in your component’s HTML using contacts.data or contacts.error.
3. Using Wired Function
Instead of wiring to a property, you can also wire to a function to further process the data or handle errors:
@wire(getContacts)
wiredContacts({ error, data }) {
if (data) {
this.contacts = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.contacts = undefined;
}
}
Advantages of Using Wire Service:
- Reactivity: When the data source changes (e.g., Salesforce records), the component automatically re-renders to reflect those changes.
- Caching: Salesforce caches the data, reducing the need for duplicate server trips for the same data.
Calling an Apex Method Imperatively in LWC
Calling an Apex method imperatively means invoking the method directly, often in response to a particular action or event like a button click. This approach provides more control over when the method gets called.
1. Setting Up the Apex Method
Much like the wire service, the Apex method needs the @AuraEnabled annotation. However, for imperative calls, the cacheable attribute isn’t mandatory.
Consider an Apex method to add a new contact:
public with sharing class ContactController {
@AuraEnabled
public static Contact addContact(String name, String email) {
Contact newContact = new Contact(Name=name, Email=email);
insert newContact;
return newContact;
}
}
2. Importing the Apex Method
In your LWC’s JavaScript file, import the method:
import addContact from ‘@salesforce/apex/ContactController.addContact’;
3. Calling the Apex Method Imperatively
You can now call this method in response to an action, like a button click:
handleAddContact() {
const name = ‘John Doe’;
const email = ‘john.doe@example.com’;
addContact({ name: name, email: email })
.then(result => {
console.log(‘Contact added with ID’, result.Id);
})
.catch(error => {
console.error(‘Error adding contact’, error);
});
}
Here, addContact returns a Promise, so you handle the response using .then() and catch any errors with .catch().
Advantages of Imperative Calls:
- Direct Control: You decide when to call the method. It’s especially useful for actions based on user interactions.
- Flexibility: Easily pass parameters to your Apex method, as demonstrated in the addContact example.
Drawbacks:
- Lack of Reactivity: Unlike @wire, imperative calls don’t automatically react to data changes.
- No Built-in Caching: You don’t benefit from the automatic caching that @wire offers. However, you can use cacheable actions if the method is read-only.
While the wire service in LWC provides an automatic, reactive link to your Apex data, imperative calls offer a more hands-on, controlled interaction. Which one you choose depends on your component’s needs and your specific situation.
Conclusion
As the world of Salesforce continues to expand and evolve, staying connected with a community of like-minded professionals can be invaluable. The knowledge you gain from our deep dives into Lightning Web Components and Apex is just the tip of the iceberg.
Whether you’re aspiring to be a Salesforce Admin or aiming to advance as a Salesforce Developer, we’ve got resources tailored just for you.
Check out our Salesforce Developer Online Training program with capstone projects.
Sign up with saasguru today and unlock a world of opportunities!
Join our saasguru community on Slack to share insights, ask questions, and get real-time feedback from experienced peers.