I have a string which I am trying to deserialize to a wrapperclass / object. But get the error:
Expected Map<String,String> but found [line:1, column:3]
Wrapperclass
global class Invocable_Obj_HandleInvoice {
@AuraEnabled global Id invoiceId;
@AuraEnabled global string invoiceNumber;
@AuraEnabled global decimal balanceAmount;
@AuraEnabled global decimal totalAmount;
@AuraEnabled global string customerName;
@AuraEnabled global string zuoraStatus;
@AuraEnabled global string handlingStatus;
@AuraEnabled global string selectedOption;
@AuraEnabled global Map<String, String> availableOptions;
}
String
[
{
"availableOptions": [
{
"key": "e",
"value": "f"
},
{
"key": "g",
"value": "z"
}
],
"balanceAmount": -100,
"customerName": "Test",
"handlingStatus": "New",
"invoiceId": "a0S2o000023CSHoEAO",
"invoiceNumber": "INV-001",
"selectedOption": "A",
"totalAmount": -100,
"zuoraStatus": "Posted"
},
{
"availableOptions": [
{
"key": "a",
"value": "x"
},
{
"key": "b",
"value": "y"
},
{
"key": "c",
"value": "z"
}
],
"balanceAmount": -100,
"customerName": "Test",
"handlingStatus": "New",
"invoiceId": "a0S2o000023CSHoEAO",
"invoiceNumber": "INV-001",
"selectedOption": "y",
"totalAmount": -100,
"zuoraStatus": "Posted"
}
]
Apex
system.debug((List<Invocable_Obj_HandleInvoice>) System.JSON.deserialize(invoices, List<Invocable_Obj_HandleInvoice>.class));
List passed to lightning component
List<Invocable_Obj_HandleInvoice> hiList = new List<Invocable_Obj_HandleInvoice>();
Invocable_Obj_HandleInvoice hi1 = new Invocable_Obj_HandleInvoice();
hi1.invoiceId = zi[0].id;
hi1.invoiceNumber = zi[0].Name;
hi1.balanceAmount = zi[0].Zuora__Balance2__c;
hi1.totalAmount = zi[0].Zuora__TotalAmount__c;
hi1.customerName = 'Test';
hi1.zuoraStatus = zi[0].Zuora__Status__c;
hi1.handlingStatus = zi[0].Handling_Status__c;
hi1.selectedOption = 'A';
hi1.availableOptions = new Map<String,string> {'e'=>'f', 'g'=> 'z'};
hiList.add(hi1);
return hiList;
Lightning controller
var act = cmp.get("c.updateInvoices");
var updatedInvoiceList = JSON.stringify(cmp.get('v.handleInvoices'));
act.setParams({ "invoices" : updatedInvoiceList});
$A.enqueueAction(act);
Component <aura:attribute type="List" name="handleInvoices"/>
Lightning controller
doInit : function(cmp, event, helper) {
var action = cmp.get("c.testHandlInvoice");
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
cmp.set('v.handleInvoices', response.getReturnValue());
console.log(cmp.get('v.handleInvoices'));
}
});
$A.enqueueAction(action);
},
console.log
availableOptions: Array(3)
0: {key: "a", value: "x"}
1: {key: "b", value: "y"}
2: {key: "c", value: "z"}
length: 3
__proto__: Array(0)
balanceAmount: -100
customerName: "Test"
handlingStatus: "New"
invoiceId: "a0S2o000023CSHoEAO"
invoiceNumber: "INV-001"
selectedOption: "A"
totalAmount: -100
zuoraStatus: "Posted"
UPDATE***** For anyone bumping into this issue I figured out the answer below addresses the issue of the map but after stringify the map is still altered so I ended combining this solution passing the object directly: How to pass an object from a Lightning Component helper to an Apex Controller method
var act = cmp.get("c.updateInvoices");
var tempInvoiceList = cmp.get('v.handleInvoices');
tempInvoiceList = tempInvoiceList.slice(); // copy
tempInvoiceList = tempInvoiceList.map(function(invoice) { return Object.assign({}, invoice); }); // copy deeper
act.setParams({ "invoices" : tempInvoiceList});
tempInvoiceList = tempInvoiceList
.forEach(function(invoice) {
invoice.availableOptions = invoice.availableOptions
.reduce(function(prev, option) {
prev[option.key] = option.value;
return prev;
},
{})
}
);
$A.enqueueAction(act);