Most of the time we need to use the existing apex method which accepts custom wrapper objects as a parameter. This post will help in sending wrapper object to apex from LWC.
There are two ways to pass the custom type or complex data to apex from LWC.
1. Sending Wrapper object to Apex
We can directly pass wrapper object to apex without any serialization and deserialization process. Let us take an example we have below wrapper class or DTO class in the apex
public class AccountWrapper
{
@auraenabled
public string Name{get;set;}
@auraenabled
public integer NumberOfEmployees{get;set;}
@AuraEnabled
public List<Contact> Contacts { get; set; }
}
This wrapper object is used in apex class to get data from LWC to insert Account and Contact objects. Use cases can be different for your project where you need to get complex data from LWC.
public class AccountService {
@auraenabled
public static void createAccountContact(AccountWrapper wrapper)
{
system.debug('wrapper:'+wrapper);
if(wrapper!=null)
{
Account act=new Account();
act.Name=wrapper.Name;
act.NumberOfEmployees=wrapper.NumberOfEmployees;
insert act;
if(wrapper.Contacts!=null)
{
for(Contact ct:wrapper.Contacts)
{
ct.AccountId=act.id;
}
insert wrapper.Contacts;
}
}
}
}
To pass this AccountWrapper wrapper object to apex we have to pass JSON data in method parameter in LWC. This is similar to the normal parameter passed to apex. Before we call any apex method we have to reference that method using import in LWC. So according to your method change it in LWC code.
import { LightningElement } from 'lwc';
import createAccountContact from '@salesforce/apex/AccountService.createAccountContact';
export default class ApexWrapperCall extends LightningElement {
contacts=[];
error;
handleClick(e)
{
var contact=
{
LastName:'Sahni',
Email:'salesforcecodex@gmail.com',
Phone:'9871506648'
};
this.contacts.push(contact);
var pass=
{
Name:'Dhanik',
NumberOfEmployees:2,
Contacts:this.contacts
};
createAccountContact({wrapper:pass})
.then(result => {
console.log('Data:'+ JSON.stringify(result));
}) .catch(error => {
console.log(error);
this.error = error;
});
}
}
Here is the output of apex where complete data is passed to apex.
2. Send serialized string to Apex and deserialize it
Passing wrapper to Apex using the first approach will work in the most scenario but if it is not working then pass wrapper data using serialized string. This serialized string will be deserialized as a wrapper object (Apex object) in the Apex class.
JSON.deserialize method will be used to deserialize string into wrapper object.
AccountWrapper wrapper=(AccountWrapper)JSON.deserialize(wrapperText,AccountWrapper.class);
Apex Code:
We expect data in this method as a string. After getting the string we are converting the string in the AccountWrapper object.
public class AccountService {
public class AccountWrapper
{
@auraenabled
public string Name{get;set;}
@auraenabled
public integer NumberOfEmployees{get;set;}
@AuraEnabled
public List<Contact> Contacts { get; set; }
}
@auraenabled
public static void createAccountContacts(string wrapperText)
{
system.debug('wrapperText:'+wrapperText);
AccountWrapper wrapper=(AccountWrapper)JSON.deserialize(wrapperText,AccountWrapper.class);
system.debug('wrapper:'+wrapper);
if(wrapper!=null)
{
Account act=new Account();
act.Name=wrapper.Name;
act.NumberOfEmployees=wrapper.NumberOfEmployees;
insert act;
if(wrapper.Contacts!=null)
{
for(Contact ct:wrapper.Contacts)
{
ct.AccountId=act.id;
}
insert wrapper.Contacts;
}
}
}
}
LWC Code to pass wrapper object as a string:
In LWC we have to create JSON objects like account variable in the below code. After creating JSON object convert it into a string to pass the apex.
import { LightningElement } from 'lwc';
import createAccountContacts from '@salesforce/apex/AccountService.createAccountContacts';
export default class ApexWrapperCall extends LightningElement {
contacts=[];
error;
handleClick(e)
{
var contact=
{
LastName:'Sahni',
Email:'salesforcecodex@gmail.com',
Phone:'9871506648'
};
this.contacts.push(contact);
var account=
{
Name:'Dhanik Sahni',
NumberOfEmployees:2,
Contacts:this.contacts
};
createAccountContacts({wrapperText:JSON.stringify(account)})
.then(result => {
console.log('Data:'+ JSON.stringify(result));
}) .catch(error => {
console.log(error);
this.error = error;
});
}
}
This will give output like the below image
References:
Stop Serialization and Deserialization of Object In Apex
Handle Heap Size for Apex Code Optimization
Data Transformation with DataWeave in Salesforce Apex
Secure Apex Code with User Mode Operation
Object Initializer in Salesforce Apex
Enhance Apex Performance with Platform Caching