
Did you know that you can pass complex types of data from Lightning Web Components to Apex controllers?
I’ve recently implemented a Lightning data table with pagination and sorting so I’ve created a data structure “queryParameters” like this (*):
@track queryParameters = {
sortFieldName: '',
sortDirection: '',
pageNumber: 1,
pageSize: 8
};
Then I’ve referenced the queryParameters variable in a @wire call to an Apex controller as below:
@wire( getAvailableRecords, { queryParameters: '$queryParameters' } )
Then found a couple of interesting details:
- The Apex method will require a Map<Object, Object> or Map<Object, String> for complex/composite Javascript types such as “queryParameters”. The parameter will not be received if you declare it as a class with @AuraEnabled members. You will have to receive it as a Map instead.
- If you change a member of the object queryParameters, even though you’ve annotated it with @track (*), it won’t track and the component will not rerender. You will have to modify the queryParameters object entirely – instead of just one of its members – to cause the expected reaction (that is, the @wire method should be called when queryParameters changes).
So I’ve ended up coding the changes to queryParameters like below, to cause @track to not ignore changes:
this.queryParameters = {
...this.queryParameters,
pageNumber: pageNumber
};
...
// refresh data when sorting criteria is changed
this.queryParameters = {
...this.queryParameters,
sortFieldName: fieldName,
sortDirection: sortDirection
}
(*) @track is no longer needed since Spring ’20 release and all fields in a LWC class are reactive. @track was mentioned to make the point clear.
It is interesting though that the observed behavior is exactly opposite of what is described in Spring ’20 and has been reported as a bug.
Thanks to Krishna Teja for this article that gave more clarity on passing complex data types from LWC to Apex!
Leave a Reply