1

I am new to Lightning and am going through the Lightning Components Basics module.

In the expensesHelper.js file would like to find out if it's possible to move the callback function definition inside the setCallback function's input parameters to its own function and pass this function's name in the arguments instead.

Instead of this:

({ 
    createExpense: function(component, expense) {
        var action = component.get("c.saveExpense");
        action.setParams({
            "expense": expense
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var expenses = component.get("v.expenses");
                expenses.push(response.getReturnValue());
                component.set("v.expenses", expenses);
            }
        })
        $A.enqueueAction(action);
    },


})

I would like to move the callback function defintion out into its own function like this:

 ({ 
     createExpense: function(component, expense) {
         var action = component.get("c.saveExpense");
         action.setParams({
            "expense": expense
        });
         action.setCallback(this, this.cbackfunction);
         $A.enqueueAction(action);
     },


    cbackfunction: function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var expenses = component.get("v.expenses");
                expenses.push(response.getReturnValue());
                component.set("v.expenses", expenses);
            }
        }

})

With the code above I am getting the run-time error: "Error in $A.getCallback() [component is not defined] Callback failed: apex://ExpensesController/ACTION$saveExpense Failing descriptor: {c:expenses}"

I added a console log to make sure that "this.cbackfunction" exists and it does:

console.log("this.cbackfunction: " + this.cbackFunction);
this.cbackfunction: function (response) {
   var state = response.getState();
   var expenses = component.get("v.expenses");
   expenses.push(response.getReturnValue()); 
   component.set("v.expenses", expenses);
}

So, the cbackfunction function is visible from within the createExpense function.

Any ideas on how to call setCallback with a callback function?

1

You can move the body into another method, but you need to put a method inside the callback to call the other method to preserve the parameter:

({ 
     createExpense: function(component, expense) {
         var action = component.get("c.saveExpense");
         action.setParams({
            "expense": expense
        });
         action.setCallback(this, 
             response => this.cbackfunction(component, response));
         $A.enqueueAction(action);
     },
    cbackfunction: function(component, response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var expenses = component.get("v.expenses");
                expenses.push(response.getReturnValue());
                component.set("v.expenses", expenses);
            }
        }
})
  • Thank you @sfdcfox, that worked. Could you please explain why my code didn't work and yours did? I am new to lightning and don't know much about javascript either. I come from a C, C# background. The "==>" syntax reminds me of pointers to struct members in C. – user54373 Mar 2 '18 at 12:18
  • @user54373 x => y is basically function(x) { return y; } shorthand. You're creating a closure that can pass the component reference to the next function call. In your original code, component was out of scope and could not be referenced. You might want to read more about arrow functions, as they're incredibly useful. Notably, arrow functions preserve "this", which is also needed to make sure you can call the function using this. – sfdcfox Mar 2 '18 at 13:03

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.