2

I've two functions in a component helper, which calls another function like below:

 ({
    data1: null,
    data2: null,
    data: null,

    get1 : function(component) {
        var action = component.get("c.UserDetails");
        action.setCallback(this, function(response) {
          var state = response.getState();
          if (component.isValid() && state === "SUCCESS") {
            this.data1 = response.getReturnValue();
            console.log('get1:', this.data1 , this.data2);
            this.process(component);
          }
        });
        $A.enqueueAction(action);
    },
    get2 : function(component) {
        this.data2 = 35;
        console.log('get2:', this.data1 , this.data2);
        this.process(component);
    },
    process : function(component) {
        console.log('process:', this.data1 , this.data2);
        if(this.data1 && this.data2) {
            this.data = {name: this.data1.FirstName, age: this.data2};
            component.set('v.user', this.data);
        }
    }
})

Controller

({
    doInit : function(component, event, helper) {

        helper.get1(component);
        helper.get2(component);
    }
})

Component

<aura:component controller="LightningLearnerController" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="user" type="object" />
    <div>Name: {!v.user.name}</div>
    <div>Age: {!v.user.age}</div>
</aura:component>

This was working fine until I enabled Lightning LockerService Security. When I set either data1 or data2 the other is being set to undefined, hence the process function is never executed as the if loop condition is always false.

Any pointers/suggestions on how to fix are most welcome.

Thanks.

5

The problem in your code is the use of this keyword inside of the action's callback function.

Every JS function has a this,and the value of this is determined by how a function is called and it behaves differently in strict mode which is enforced by the LockerService(for more info on this can be found here ).

This is what happening inside the get1:

get1 : function(component) {
        var action = component.get("c.UserDetails");
        var self = this;
        // THIS points to the Helper's context where the `data1,data2,data,other helper functions` resides
        console.log(this) // THIS is different from below THIS inside of the action 
        action.setCallback(this, function(response) {
            /* 
            THIS point to the action's(i.e ActionService) context, 
            because its the one that invoked the callback function
            */
            console.log(this); 
            console.log(this === self); // return false
        });
}

So, all you have to do is store the helper's context in variable, and use it to call other helper methods inside the actions's callback like this:

get1 : function(component) {
        var action = component.get("c.UserDetails");
        var self = this;
        action.setCallback(this, function(response) {
          var state = response.getState();
          if (component.isValid() && state === "SUCCESS") {
            self.data1 = response.getReturnValue();
            console.log('get1:', self.data1 , self.data2);
            self.process(component);
          }
        });
}
3
  • Thanks Praveen. Overlook :( I wonder why it is working when LockerService is disabled. Jun 12 '16 at 11:06
  • 1
    @SuryaChandraRaoGandreddi As Praveen pointed out that Locker Service makes enforces your Javascript to use "strict" mode .Refer the link thats been added in the answer Jun 12 '16 at 12:02
  • @praveen Great answer ! Jun 12 '16 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.