Unable to use the latest attribute value set by helper class in the controller class (Aura/Lightning)

lightning-aura-components

In Component I have attribute as shown below:

<aura:attribute name="myAttribute" type="Boolean" default =false/>  

In Controller I have code like this:

Method that is calling helper method to get the latest value of the attribute

var myValue=c.get("v.myAttribute");  

In Helper I'm calling an apex method and based on that I'm setting the value of attribute:

c.set("v.myAttribute",'true');  

When I'm trying to get the attribute value in the controller, it is always showing the value as false which should have been true since the helper method already set the value to true.

Original code:

Attribute in lightning component –

    <aura:attribute name="hasexistingInvoicesbeforeDelete" type="boolean" default="false"/> 

Method in Controller.js –

deleteContinue: function(component, event, helper) {
        helper.checkbeforDelete(component, event);
        var existingInvs = component.get("v.hasexistingInvoicesbeforeDelete");

       
        alert('check...'+existingInvs);
        if(existingInvs){
            helper.errorDeletingToast(component, event);
          //  helper.deletePromHistData(component,event);
        }
       else{
            helper.deletePromHistData(component,event);
        }
   
        // helper.checkExistingInvoices(component,event);
        component.set("v.isdelete", false);
        },

Method in helper class:

checkbeforDelete: function(component, event){
        alert('in helper');
        var action = component.get("c.checkExistingInvoicesonDelete");
        action.setParams({
            "contactId": component.get("v.contid"),
            "ProgInfoId": component.get("v.delProgId")
        });
    
        action.setCallback(this, function(response){    
            var state = response.getState();
            
            if (state === "SUCCESS") {
                var responseResult = response.getReturnValue();
                if(responseResult=='InvsFound'){
                    alert('Inv found');
                    component.set("v.hasexistingInvoicesbeforeDelete",'true');
                   }
                   else{
                    alert('Inv not found');
                   }
            } 
        });
        $A.enqueueAction(action);
    
       },

Apex class Method –

 @AuraEnabled
  public static string checkExistingInvoicesonDelete(string contactId, string ProgInfoId ) {
      system.debug('here$$$$');
      Component_Program_Information__c prg = [select id, Provider__c from Component_Program_Information__c where id=:ProgInfoId];
      string accid = prg.Provider__c;
      List<Invoice__c> invs = [select id, status__c, Account__c from Invoice__c  where Account__c=:accId and (status__c='Submitted for Review' OR status__c = 'Approved')  LIMIT 1];
    if(!invs.isEmpty()){
       return 'InvsFound';
    }
    else{
       return 'InvsnotFound';
    }        
 }

Best Answer

You're checking for a value before a value is returned from the server. Calls to the server are asynchronous, meaning they will not be called before later code in the same function. You need to wait for the server call to return. We do this by using a Promise.

checkbeforDelete: function (component, event) {
    return new Promise((resolve, reject) => {
    var action = component.get("c.checkExistingInvoicesonDelete");
    action.setParams({
        contactId: component.get("v.contid"),
        ProgInfoId: component.get("v.delProgId"),
    });
    action.setCallback(this, function (response) {
        var state = response.getState();
        if (state === "SUCCESS") {
        var responseResult = response.getReturnValue();
        component.set("v.hasexistingInvoicesbeforeDelete", "true");
        } else {
        alert("Inv not found");
        }
        resolve(responseResult);
        if (state === "ERROR") {
        reject(response.getError());
        }
    });
    $A.enqueueAction(action);
    });
},

To complete the wait, we'll use .then:

deleteContinue: function (component, event, helper) {
    helper.checkbeforDelete(component, event).then((result) => {
    var existingInvs = component.get("v.hasexistingInvoicesbeforeDelete");
    alert("check..." + existingInvs);
    if (existingInvs) {
        helper.errorDeletingToast(component, event);
        //  helper.deletePromHistData(component,event);
    } else {
        helper.deletePromHistData(component, event);
    }
    // helper.checkExistingInvoices(component,event);
    component.set("v.isdelete", false);
    })
    .catch(error => {
        // you can handle errors here
    });
},
Related Topic