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);
        })
    );
},
2
  • Add reject in error and check if you are getting any error Commented May 20, 2020 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
    Commented May 20, 2020 at 3:33

1 Answer 1

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();
      })
    );
  },
});
6
  • 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
    Commented May 20, 2020 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
    Commented May 20, 2020 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
    Commented May 20, 2020 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
    Commented May 20, 2020 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
    Commented May 20, 2020 at 5:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .