Seems Spring 19 wants stricter typing for aura attributes, but I'm not finding any best practices on how to approach this.
This use to work in Winter 19:
MainController.js
let myData = {
parentId: "123abc",
sourceData: [
{
childId: "1",
Some_Bool_Field__c: true
},
{
childId: "2",
Some_Bool_Field__c: true
}
]
}
helper.engineService(component).sendMyData(
myData
)
EngineService.cmp
<aura:method name="sendMyData" action="{! c.handleSendMyData }">
<aura:attribute name="data" type="Object"/>
</aura:method>
EngineServiceController.js
handleSendMyData : function(component, event, helper) {
var params = event.getParam("arguments");
var action = component.get("c.goGetMyData");
action.setStorable();
action.setParams({
data : params.data
});
helper.dispatchAction(component, action, params); //enqueues action
},
Server
@AuraEnabled
public static Map<String, Object> goGetMyData(Map<String, Object> data) {
// In Spring 19, we don't even see this next line
System.debug('appendEngineCache data: '+data);
// winter 19 use to parse these correctly
Id recordId = (Id)data.get('parentId');
List<Children__c> someChildren = (List<Children__c>)data.get('sourceData');
// more
}
In Spring 19, I'm not seeing any serverside debugs other than enter and immediately exit Aura with this client-side error:
"Value provided is invalid for action parameter 'data' of type 'Map'"
Here's what I've tried so far with no success:
- change aura attribute type
Object
toMap
(with and w/odefault="{}"
). - change serverside argument from
Map<String, Object>
toObject
and it gacks
Here's what works, but not ideal (so I'm looking for alternatives)
- Use
JSON.stringify(data)
and changing apex argument toString
then useMap<String, Object> parsedData = (Map<String, Object>)JSON.deserializedUntyped(data)
inside the method. - Then, continue to use
parsedData
in any downstream Apex.
Anyone found any alternatives without that additional type coercion overhead?
EDIT: Possible solution until more info?
Given that existing unit / integration tests sometimes need to call these methods (with Map<String, Object> parameters
), this is the least path of resistance I've found is to overload existing method AND use JSON.stringify
at some point in clientside.
Client
action.setParams({
data : JSON.stringify(params.data)
});
Server
@AuraEnabled
public static Map<String, Object> goGetMyData(String data) {
return goGetMyData((Map<String, Object>)JSON.deserializeUntyped(data));
}
@TestVisible
private static Map<String, Object> goGetMyData(Map<String, Object> data) {
// all existing code
// but @TestVisible added and switched over to private so aura component doesn't find the wrong one.
}