Documentation Index Fetch the complete documentation index at: https://mintlify.com/trailheadapps/lwc-recipes/llms.txt
Use this file to discover all available pages before exploring further.
This component demonstrates how to call an Apex method imperatively with complex parameters, including custom Apex wrapper classes with nested data structures.
Implementation
apexImperativeMethodWithComplexParams.js
apexImperativeMethodWithComplexParams.html
ApexTypesController.cls
CustomWrapper.cls
import { LightningElement } from 'lwc' ;
import checkApexTypes from '@salesforce/apex/ApexTypesController.checkApexTypes' ;
export default class ApexImperativeMethodWithComplexParams extends LightningElement {
listItemValue = 4 ;
numberValue = 50 ;
stringValue = 'Some string' ;
message ;
error ;
handleStringChange ( event ) {
this . stringValue = event . target . value ;
}
handleNumberChange ( event ) {
this . numberValue = event . target . value ;
}
handleListItemChange ( event ) {
this . listItemValue = event . target . value ;
}
async handleButtonClick () {
// Creating the object that represents the shape
// of the Apex wrapper class.
let parameterObject = {
someString: this . stringValue ,
someInteger: this . numberValue ,
someList: []
};
// Populating a list
for ( let i = 0 ; i < this . listItemValue ; i ++ ) {
parameterObject . someList . push ( this . stringValue );
}
// Calling the imperative Apex method with the JSON
// object as parameter.
try {
this . message = await checkApexTypes ({ wrapper: parameterObject });
this . error = undefined ;
} catch ( error ) {
this . message = undefined ;
this . error = error ;
}
}
}
Key Features
Complex Object Construction
Create JavaScript objects that match the structure of Apex wrapper classes:
let parameterObject = {
someString: this . stringValue ,
someInteger: this . numberValue ,
someList: []
};
Property Name Mapping
JavaScript object properties must match Apex class property names:
// JavaScript
{
someString : 'value' ,
someInteger : 42 ,
someList : [ 'item1' , 'item2' ]
}
// Apex
public class CustomWrapper {
@AuraEnabled
public String someString { get ; set ; }
@AuraEnabled
public Integer someInteger { get ; set ; }
@AuraEnabled
public List < String > someList { get ; set ; }
}
Dynamic List Population
Build arrays dynamically before sending to Apex:
for ( let i = 0 ; i < this . listItemValue ; i ++ ) {
parameterObject . someList . push ( this . stringValue );
}
Parameter Passing
Pass the complex object as a named parameter:
this . message = await checkApexTypes ({ wrapper: parameterObject });
// ^
// Parameter name matches Apex method
Properties
Property Type Description stringValueString String value to send to Apex numberValueNumber Integer value to send to Apex listItemValueNumber Number of items to include in the list messageString Response message from Apex errorObject Error object if the call fails
Parameters
JavaScript Object Structure
{
someString : String ,
someInteger : Number ,
someList : Array < String >
}
Apex Method Parameters
Parameter Type Description wrapperCustomWrapper Custom wrapper object containing complex data
Apex Wrapper Class Requirements
AuraEnabled annotation : All properties must be annotated
Public access : Properties must be public
Get/Set methods : Use { get; set; } syntax
Sharing rules : Use with sharing for security
public with sharing class CustomWrapper {
@AuraEnabled
public String someString { get ; set ; }
@AuraEnabled
public Integer someInteger { get ; set ; }
@AuraEnabled
public List < String > someList { get ; set ; }
}
Type Mapping
Primitive Types
JavaScript Apex String String Number Integer, Decimal, Double Boolean Boolean null null
Complex Types
JavaScript Apex Object Custom Apex class, sObject Array List Date Date, DateTime
Advanced Examples
Nested Objects
// JavaScript
let complexObject = {
customer: {
name: 'John Doe' ,
email: 'john@example.com'
},
items: [
{ name: 'Item 1' , price: 100 },
{ name: 'Item 2' , price: 200 }
]
};
await processOrder ({ order: complexObject });
// Apex
public class OrderWrapper {
@AuraEnabled public CustomerWrapper customer { get ; set ; }
@AuraEnabled public List < ItemWrapper > items { get ; set ; }
}
public class CustomerWrapper {
@AuraEnabled public String name { get ; set ; }
@AuraEnabled public String email { get ; set ; }
}
public class ItemWrapper {
@AuraEnabled public String name { get ; set ; }
@AuraEnabled public Decimal price { get ; set ; }
}
sObject Parameters
// JavaScript
let contact = {
FirstName: 'John' ,
LastName: 'Doe' ,
Email: 'john@example.com'
};
await createContact ({ contactRecord: contact });
// Apex
@AuraEnabled
public static Id createContact ( Contact contactRecord ) {
insert contactRecord ;
return contactRecord . Id ;
}
List of sObjects
// JavaScript
let contacts = [
{ FirstName: 'John' , LastName: 'Doe' },
{ FirstName: 'Jane' , LastName: 'Smith' }
];
await createMultipleContacts ({ contactList: contacts });
// Apex
@AuraEnabled
public static List < Id > createMultipleContacts ( List < Contact > contactList ) {
insert contactList ;
List < Id > ids = new List < Id >();
for ( Contact c : contactList ) {
ids . add ( c . Id );
}
return ids ;
}
Error Handling
Handle errors for complex parameter validation:
try {
this . message = await checkApexTypes ({ wrapper: parameterObject });
this . error = undefined ;
} catch ( error ) {
this . message = undefined ;
this . error = error ;
// Error could be:
// - Invalid parameter structure
// - Type mismatch
// - Apex execution error
}
When to Use
Use complex parameters when:
Sending multiple related values
Working with nested data structures
Passing sObjects or custom types
Building objects dynamically
Sending data from forms with multiple fields
Best Practices
Match property names exactly : JavaScript object properties must match Apex class properties (case-sensitive)
Use wrapper classes : Create dedicated Apex classes for complex parameters
Validate before sending : Check data integrity in JavaScript
Document structure : Clearly document the expected object shape
Handle type conversion : Be aware of JavaScript to Apex type mapping
Use meaningful names : Name properties clearly for maintainability
Test edge cases : Test with null values, empty arrays, etc.
Common Pitfalls
Case sensitivity : someString ≠ somestring
Type mismatches : Sending String when Apex expects Integer
Missing @AuraEnabled : Apex properties must be annotated
Null handling : JavaScript undefined becomes null in Apex
Date formats : Use ISO format for dates