I'm currently stuck at a problem and was hoping someone here could help me. I also certainly hope this is the right place to ask it.
I'm trying to create a custom Invoice record with its corresponding Invoice Line records upon firing an event. I already have some logic in place to gather ID of selected rows in the JS.
I've gone so far as to be able to create the Invoice record (using LDS) and the Invoice Line records (using Apex), but can't seem to pass the Invoice ID for the Invoice Line records. I know I'm able to create the records because it works when I tested this with a hardcoded Invoice ID.
Would it be possible to pass multiple parameters of List and String to an Apex method in LWC?
I would appreciate any help. Thanks in advance!
JS
selectedRowsEvent(event) {
...some codes here...
this.selectedRecords = Array.from(conIds);
}
handleSave() {
**invId;**
...some codes here...
createRecord(recordInput)
.then(invoice => {
**this.invId = invoice.Id;**
**createInvLines({ lstConIds : this.selectedRecords, invoiceId : this.invId})**
}).catch(error => {
...some codes here...
});
}
Controller
@AuraEnabled
public static void createInvLines(list<Id> lstConIds, string invoiceId){
if(lstConIds.size() > 0){
List<OpportunityLine__c> oppLst = new List<OpportunityLine__c>([SELECT Id, Description__c FROM OpportunityLine__c WHERE Id = :lstConIds]);
try {
List<InvoiceLine__c> lstInvLinesToInsert = new List<InvoiceLine__c>();
for(OpportunityLine__c idCon : oppLst) {
lstInvLinesToInsert.add(new InvoiceLine__c(**InvoiceId__c = invoiceId**, Description__c = idCon.Description__c));
}
if(!lstInvLinesToInsert.isEmpty()) {
insert lstInvLinesToInsert;
}
}
catch(Exception ex) {
throw new AuraHandledException(ex.getMessage());
}
}
}
I'm currently stuck at a problem and was hoping someone here could help me. I also certainly hope this is the right place to ask it.
I'm trying to create a custom Invoice record with its corresponding Invoice Line records upon firing an event. I already have some logic in place to gather ID of selected rows in the JS.
I've gone so far as to be able to create the Invoice record (using LDS) and the Invoice Line records (using Apex), but can't seem to pass the Invoice ID for the Invoice Line records. I know I'm able to create the records because it works when I tested this with a hardcoded Invoice ID.
Would it be possible to pass multiple parameters of List and String to an Apex method in LWC?
I would appreciate any help. Thanks in advance!
JS
selectedRowsEvent(event) {
...some codes here...
this.selectedRecords = Array.from(conIds);
}
handleSave() {
**invId;**
...some codes here...
createRecord(recordInput)
.then(invoice => {
**this.invId = invoice.Id;**
**createInvLines({ lstConIds : this.selectedRecords, invoiceId : this.invId})**
}).catch(error => {
...some codes here...
});
}
Controller
@AuraEnabled
public static void createInvLines(list<Id> lstConIds, string invoiceId){
if(lstConIds.size() > 0){
List<OpportunityLine__c> oppLst = new List<OpportunityLine__c>([SELECT Id, Description__c FROM OpportunityLine__c WHERE Id = :lstConIds]);
try {
List<InvoiceLine__c> lstInvLinesToInsert = new List<InvoiceLine__c>();
for(OpportunityLine__c idCon : oppLst) {
lstInvLinesToInsert.add(new InvoiceLine__c(**InvoiceId__c = invoiceId**, Description__c = idCon.Description__c));
}
if(!lstInvLinesToInsert.isEmpty()) {
insert lstInvLinesToInsert;
}
}
catch(Exception ex) {
throw new AuraHandledException(ex.getMessage());
}
}
}
Share
Improve this question
edited Aug 22, 2020 at 4:04
Herohtar
5,6134 gold badges33 silver badges42 bronze badges
asked Apr 29, 2020 at 4:12
Sid FortunatoSid Fortunato
331 gold badge1 silver badge7 bronze badges
1
- 1 It turns out that it was a case sensitivity issue. Changing "this.invId = invoice.Id" to "this.invId = invoice.id" resolved the issue. I would have never for the life of me would've figured that out without any help. I've marked eyescream's answer because that is definitely a much better to write this, and would be doing so in the future. – Sid Fortunato Commented Apr 29, 2020 at 13:28
2 Answers
Reset to default 3Yes, you can pass plex parameters to methods marked as @AuraEnabled
. On client side it'll be a JSON object with right field names, like you already have { lstConIds : this.selectedRecords, invoiceId : this.invId}
. On Apex side it can be a function with multiple arguments or just 1 argument (some helper wrapper class, again with right field names). Salesforce will "unpack" that JSON for you and put into right fields before your code is called.
Your preference which would be cleaner. I tend to use wrappers. If you have a reusable service-like function and you want to add some optional parameters later - you'd simply put new field in wrapper class and job done. Might be not as easy to add a new parameter to function used in other apex code, bit messier.
(in your scenario I'd definitely try to create invoice and line items as 1 call so if anything fails - the normal transaction rollback will help you. if one of items fails - you don't want to be left with just invoice header, right?)
Have you seen https://developer.salesforce./docs/ponent-library/documentation/en/lwc/lwc.apex ? it's a wall of text but it mentions interesting example, search for "apexImperativeMethodWithParams" in there.
Look at JS file here: https://github./trailheadapps/lwc-recipes/tree/master/force-app/main/default/lwc/apexImperativeMethodWithComplexParams And see how it calls
ApexTypesController {
@AuraEnabled(cacheable=true)
public static String checkApexTypes(CustomWrapper wrapper) {
...
Where CustomWrapper is
public with sharing class CustomWrapper {
class InnerWrapper {
@AuraEnabled
public Integer someInnerInteger { get; set; }
@AuraEnabled
public String someInnerString { get; set; }
}
@AuraEnabled
public Integer someInteger { get; set; }
@AuraEnabled
public String someString { get; set; }
@AuraEnabled
public List<InnerWrapper> someList { get; set; }
}
The issue is that the inserts are asynchronous and you are firing them synchronously. So, that means you are trying to insert the lines before the parent record has pleted.
// CREATE THE INVOICE RECORD
createRecord(recordInput)
.then(invoice => {
**this.invId = invoice.Id;**
// Call the next function here
// CREATE THE INVOICE LINE RECORDS
**createInvLines({ lstConIds : this.selectedRecords, invoiceId : this.invId})**
.then(result => {
...some codes here...
})
.catch(error => {
...some codes here...
});
);
}