Streamlining Salesforce Development: Using a Wrapper Class to Pass User Input from LWC to Apex
In today's Salesforce-driven business landscape, creating efficient and scalable applications is key to delivering value. One common scenario for Salesforce developers is capturing user input from a Lightning Web Component (LWC) and sending it to an Apex Controller for processing, such as creating records like Account. Leveraging a wrapper class in this context is a highly effective way to handle complex data structures and ensure seamless communication between LWC and Apex.
In this article, we’ll walk through a practical example of how to use a wrapper class to pass user input values from an LWC component to Apex and save the Account record.
What is a Wrapper Class?
A wrapper class in Apex is essentially a custom class that serves as a data container. It can hold multiple fields or even objects, which makes it extremely useful for passing complex data structures between front-end components (like LWC) and the back-end (Apex).
Use Case: Saving an Account Record
Let’s consider a scenario where we need to capture the user’s input for the following fields:
Our goal is to collect this information in the LWC, pass it to Apex using a wrapper class, and then save the Account record in Salesforce.
Step-by-Step Implementation
1. Apex Wrapper Class and Controller
The first step is to create an Apex wrapper class that will hold the values sent from the LWC. We'll also build a simple Apex method to handle this input and create an Account record.
Wrapper Class (AccountWrapper) :
public class AccountWrapper {
@AuraEnabled public String accountName { get; set; }
@AuraEnabled public String phone { get; set; }
@AuraEnabled public String industry { get; set; }
// Constructor
public AccountWrapper(String accountName, String phone, String industry) {
this.accountName = accountName;
this.phone = phone;
this.industry = industry;
}
}
In this class:
Apex Controller (AccountController):
public class AccountController {
@AuraEnabled
public static String createAccount(AccountWrapper wrapper) {
try {
// Create a new Account record
Account acc = new Account();
acc.Name = wrapper.accountName;
acc.Phone = wrapper.phone;
acc.Industry = wrapper.industry;
// Insert the Account into Salesforce
insert acc;
return 'Account Created Successfully: ' + acc.Id;
} catch (Exception e) {
throw new AuraHandledException('Error creating account: ' + e.getMessage());
}
}
}
2. LWC Component
Next, we create the LWC to handle the user input and pass it to the Apex controller.
LWC HTML (accountForm.html)
<template>
<lightning-card title="Create New Account" icon-name="standard:account">
<div class="slds-p-around_medium">
<lightning-input label="Account Name" name="accountName" value={accountName} onchange={handleInputChange}></lightning-input>
<lightning-input label="Phone" name="phone" value={phone} onchange={handleInputChange}></lightning-input>
<lightning-input label="Industry" name="industry" value={industry} onchange={handleInputChange}></lightning-input>
<lightning-button variant="brand" label="Save Account" onclick={saveAccount}></lightning-button>
</div>
</lightning-card>
</template>
In this template:
LWC JavaScript (accountForm.js)
import { LightningElement, track } from 'lwc';
import createAccount from '@salesforce/apex/AccountController.createAccount';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class AccountForm extends LightningElement {
@track accountName = '';
@track phone = '';
@track industry = '';
// Handles input field changes
handleInputChange(event) {
const field = event.target.name;
if (field === 'accountName') {
this.accountName = event.target.value;
} else if (field === 'phone') {
this.phone = event.target.value;
} else if (field === 'industry') {
this.industry = event.target.value;
}
}
// Save the Account using the Apex method
saveAccount() {
const wrapper = {
accountName: this.accountName,
phone: this.phone,
industry: this.industry
};
createAccount({ wrapper: wrapper })
.then(result => {
this.showToast('Success', result, 'success');
// Clear the form fields
this.accountName = '';
this.phone = '';
this.industry = '';
})
.catch(error => {
this.showToast('Error', error.body.message, 'error');
});
}
// Utility to display a toast message
showToast(title, message, variant) {
const evt = new ShowToastEvent({
title: title,
message: message,
variant: variant
});
this.dispatchEvent(evt);
}
}
In this JavaScript file:
Key Benefits of Using a Wrapper Class
Conclusion
Using a wrapper class to pass user input from an LWC component to Apex is a powerful pattern that enhances flexibility and code maintainability. It streamlines the data-handling process and makes your Salesforce applications more robust and scalable.
By following the steps outlined above, you can easily implement this functionality in your Salesforce projects, ensuring a smooth and efficient record creation process.
Have you used wrapper classes in your Salesforce projects? Share your experiences or challenges in the comments below!
#Salesforce #LightningWebComponent #Apex #SalesforceDevelopment #WrapperClass #CodingTips #recordCreation
Salesforce Developer at Coforge| Apex , LWC ,SOQL and Integration | Service,Sales and Experience ☁️
3moCould you clarify the reason for defining a constructor in the wrapper class? Since values can be passed directly from the LWC without an explicit constructor, it seems possible to insert the Account record without it.
Actively Looking For Salesforce Developer Role🚀 | Apex ✦ Lightning ⚡ | Salesforce Communities | Delivering Customized Solutions with Success 💼
9moInteresting
Senior Package Consultant (Salesforce) @ IBM || 8x Certified Salesforce Developer || Ex-Infosys || Ex-Cognizant
9moUseful tips awesome
Salesforce Certified Administrator | Certified Platform App Builder | AI Associate | Developer | 5x Superbadges | Trailhead 3 Star Ranger | USMC Veteran | ITIL | Professional Scrum Master I
9moAwesome!
Serving Notice Period :- 29 August 2025 | Salesforce Developer at Cognizant with expertise in Salesforce Service Cloud & Sales Cloud || 6x Certified
9moVery informative