I'm seeing an error when I attempt to pass a function as a parameter, but only after the containing object has made a round trip as a lightning attribute. I've reproduced this in very few lines of code as follows:
Component
<aura:component >
<aura:attribute name="obj" type="object" />
<aura:handler name="init" value="{!this}" action="{!c.init}" />
<button onclick="{!c.go}">Click Me</button>
</aura:component>
Controller
({
init : function(component, event, helper) {
helper.init(component, event);
},
go : function(component, event, helper) {
helper.go(component, event);
}
})
Helper
({
init : function(cmp, ev) {
var obj={method : function() {alert('In function');}};
cmp.set('v.obj', obj);
},
go : function(cmp) {
var obj=cmp.get('v.obj');
this.fireCallback(obj.method);
},
fireCallback : function(cb) {
cb();
}
})
The flow is:
- The component fires the init function which creates a JavaScript object with a function named 'method' and stores this as an attribute named 'obj'
- The user clicks the 'go' button which invokes the go method
- The 'obj' attribute is retrieved
- The helper method 'fireCallback' is invoked, passing the obj.method function as a parameter
- The fireCallback executes the function it received as a parameter
- The following exception occurs:
Something has gone wrong. Action failed: c$LockerTest$controller$go [Error: Permission denied to access property "$lsref"] Failing descriptor: {c$LockerTest$controller$go}. Please try again.
If I change the flow so that I invoke the obj.method function directly in the go function, everything works as expected, so it doesn't look like the locker service is blocking access to the function, it just seems to go bad when passed as a parameter to another method.
This also only happens when I store the object as an attribute and retrieve it again - which turns it into a SecureObject - so it looks like the issue is that I can't pass a SecureObject function as a parameter to another method in the same object which then invokes it.