Cara deserialize daftar dengan map ke wrapperclass
Saya memiliki string yang saya coba deserialize ke wrapperclass / object. Tapi dapatkan kesalahannya:
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;
}
Tali
[
{
"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"
}
]
Puncak
system.debug((List<Invocable_Obj_HandleInvoice>) System.JSON.deserialize(invoices, List<Invocable_Obj_HandleInvoice>.class));
Daftar diteruskan ke komponen petir
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;
Pengontrol petir
var act = cmp.get("c.updateInvoices");
var updatedInvoiceList = JSON.stringify(cmp.get('v.handleInvoices'));
act.setParams({ "invoices" : updatedInvoiceList});
$A.enqueueAction(act);
Komponen <aura: attribute type = "List" name = "handleInvoices" />
Pengontrol petir
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"
PEMBARUAN ***** Untuk siapa pun yang mengalami masalah ini, saya menemukan jawaban di bawah ini membahas masalah peta tetapi setelah merangkai peta masih diubah jadi saya akhirnya menggabungkan solusi ini dengan meneruskan objek secara langsung: Cara melewatkan objek dari a Petir Komponen pembantu ke metode Apex Controller
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);
Jawaban
@AuraEnabled global Map<String, String> availableOptions;
Seharusnya:
@AuraEnabled global List<Map<String,String>> availableOptions;
Atau:
@AuraEnabled global List<KeyValuePair> availableOptions;
Dimana KeyValuePair
:
public class KeyValuePair {
@AuraEnabled public String key;
@AuraEnabled public String value;
}
Yang cukup umum digunakan dalam kode yang sebenarnya saya miliki sebagai kelas tingkat atas di organisasi pengembang saya; Saya cukup sering menggunakannya untuk nilai daftar pilihan dan sebagainya.
JSON semacam ini umumnya tidak disarankan, tetapi jika Anda harus menggunakannya seperti itu, ini adalah bentuk yang lebih disukai. Untuk menggunakan Apex asli Anda, itu perlu diformat sebagai:
"availableOptions": { "e": "f", "g", "z" },
Begitulah JSON dimaksudkan untuk diformat dalam pengertian umum, meskipun bentuk sebelumnya dapat diterima untuk kasus-kasus seperti opsi daftar pilihan, yang memiliki nilai dan label.
Sepertinya Anda perlu mengubah "availableOptions" Anda kembali ke peta yang tepat untuk digunakan dengan benar:
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
tempInvoiceList = tempInvoiceList
.forEach(function(invoice) {
invoice.availableOptions = invoice.availableOptions
.reduce(function(prev, option) {
prev[option.key] = option.value;
return prev;
},
{})
}
);
var updatedInvoiceList = JSON.stringify(tempInvoiceLIst);
act.setParams({ "invoices" : updatedInvoiceList});
$A.enqueueAction(act);
availableOptions
di JSON Anda bukan peta, ini adalah daftar objek (dengan kolom "key" dan "value").
Jadi kelas pembungkus Anda perlu mencerminkan hal itu. Alih-alih a Map<String, String>
, Anda harus membuatnya menjadi Daftar kelas / jenis lain yang dapat menampung data target ("key" dan "value")