ラッパークラスへのマップを使用してリストを逆シリアル化する方法
ラッパークラス/オブジェクトに逆シリアル化しようとしている文字列があります。しかし、エラーが発生します:
Expected Map<String,String> but found [line:1, column:3]
ラッパークラス
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;
}
ストリング
[
{
"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"
}
]
頂点
system.debug((List<Invocable_Obj_HandleInvoice>) System.JSON.deserialize(invoices, List<Invocable_Obj_HandleInvoice>.class));
稲妻コンポーネントに渡されたリスト
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;
ライトニングコントローラー
var act = cmp.get("c.updateInvoices");
var updatedInvoiceList = JSON.stringify(cmp.get('v.handleInvoices'));
act.setParams({ "invoices" : updatedInvoiceList});
$A.enqueueAction(act);
コンポーネント<aura:attribute type = "List" name = "handleInvoices" />
ライトニングコントローラー
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 *****この問題にぶつかった人のために、以下の答えがマップの問題に対処していることを理解しましたが、文字列化した後もマップが変更されているため、オブジェクトを直接渡すこのソリューションの組み合わせを終了しました:からオブジェクトを渡す方法ApexControllerメソッドへのLightningコンポーネントヘルパー
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);
回答
@AuraEnabled global Map<String, String> availableOptions;
する必要があります:
@AuraEnabled global List<Map<String,String>> availableOptions;
または:
@AuraEnabled global List<KeyValuePair> availableOptions;
どこにKeyValuePair
ありますか:
public class KeyValuePair {
@AuraEnabled public String key;
@AuraEnabled public String value;
}
これはコードで十分に一般的に使用されているので、実際には開発者組織のトップレベルクラスとして使用しています。選択リストの値などに頻繁に使用します。
この種のJSONは一般的に推奨されていませんが、そのように使用する必要がある場合は、これが推奨される形式です。オリジナルのApexを使用するには、次のようにフォーマットする必要があります。
"availableOptions": { "e": "f", "g", "z" },
これは、JSONが一般的な意味でフォーマットされることを意味する方法ですが、値とラベルを持つ選択リストオプションのような場合には、前の形式が受け入れられます。
正しく使用するには、「availableOptions」を適切なマップに戻す必要があるようです。
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
JSONでは、マップではなく、オブジェクトのリストです(フィールド「key」と「value」を含む)。
したがって、ラッパークラスはそれを反映する必要があります。の代わりにMap<String, String>
、ターゲットデータ(「キー」と「値」)を保持できる別のクラス/タイプのリストにする必要があります。