0

I am trying to recall the apex method until I get a success response for status of log. Below is the code. checkIntegrationLog function simply check the status of a single Log and I want to call that again if the status is still pending and not complete.

This works fine, but I have called this helper method from controller and I also use .then() function to get the result from Promise but somehow when I get the success result in helper method it doesn't execute the controller stuff I have after.then() function. Any idea how to achieve this or what am I doing wrong here?

Controller.class

handleSubmit : function(component,event,helper){
    this.checkStatus(component,event,helper); //this line throws an error saying Cannot read property 'checkStatus' of undefined.
}, 
checkStatus : function (component,event,helper){
   helper.checkILogStatus(component,shiftRecord.id)
            .then(function(result) {
                console.log(JSON.stringify(result));
                if(result == true){
                    //perform after success things
                    //Here I perform action like submitting the lightning record edit form fields / hiding the spinner/ calling apex method re re-render the records details.
                } else {
                    console.log('else');
                }
                console.log('wait');
                }
            ).catch(
                function(error){
                    console.log(JSON.stringify(error));
                    component.find("sSpinner").set("v.class" , 'slds-hide');
                    helper.showToast(component,error,'error');
                }
            );
}

Helper.class

checkILogStatus : function (component, recId){
    var self = this;
    return new Promise(
        $A.getCallback(function(resolve, reject){
            var action = component.get("c.checkIntegrationLog");
            action.setParams({
             'recordId' : recId
            });
            action.setCallback(this, function(response){
                var state = response.getState();
                if (state === "SUCCESS") {
                    var res = response.getReturnValue(); // This returns a boolean value. 
                    if(res == false){
                        self.checkILogStatus(component,recId);
                    } else{
                        resolve(res);
                   }
                }else if (state === "ERROR") {
                   var errors = response.getError();
                    if (errors) {
                        if (errors[0] && errors[0].message) {
                            reject(errors[0].message);
                        }
                    } else {
                        reject("Unknown error! Please try again");
                    }
                }
            });
            $A.enqueueAction(action);
        })
    );
},
  • Add reject in error and check if you are getting any error – salesforce-sas May 20 at 3:04
  • @salesforce-sas Yes I do have reject in the else if statement I just removed the code here. I have added that code in question now. – Jenil May 20 at 3:33
1

Your problem is that you never returned a return value from the original Promise, so it's left hanging. To fix this, you need to call an inner promise loop that can call itself recursively. The following should work:

({
  checkILogStatus: function (component, recordId) {
    let callServer = function () {
      return new Promise(function (resolve, reject) {
        var action = component.get("c.checkIntegrationLog");
        action.setParams({ recordId });
        action.setCallback(this, function (response) {
          if (response.getState() === "SUCCESS") {
            resolve(response.getReturnValue());
          } else {
            reject(response.getError());
          }
        });
        $A.enqueueAction(action);
      });
    };
    return new Promise(
      $A.getCallback(function (resolve, reject) {
        let repeat = function () {
          callServer()
            .then(function (result) {
              // When true, we are done!
              result ? resolve(result) : repeat();
            })
            .catch(function (error) {
              reject(error);
            });
        };
        repeat();
      })
    );
  },
});
| improve this answer | |
  • Hi @sfdcfox, Thank you for the answer. Just a question before I go ahead and try this one out, will doing this give me the success response back in controller? Like, I want the result to go to the controller method only when the log status has been updated as 'complete'. – Jenil May 20 at 3:40
  • @Juhi Yes, your controller method looks fine. I made some assumptions about your return type, but this should be close to what you're looking for. – sfdcfox May 20 at 3:42
  • @Juhi P.S. Sorry, I returned "done getting log" back to the main controller method. Feel free to change this however you need it. – sfdcfox May 20 at 3:47
  • Thank you @sfdcfox . That worked but I have moved the controller function code which calls the helper method and does the stuff to a different function so that I can reuse it without writing the same code everywhere. I get an error if I try to use this.newFunction(); Should I be using $A.enqueueAction method thing to call the one function of controller from another function of controller? I have updated the above code for better understanding this one. – Jenil May 20 at 5:20
  • @Juhi In the controller, this is undefined. It sounds like you want to move checkStatus to the helper so it can be used from multiple locations. – sfdcfox May 20 at 5:38

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.