function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Adam TolbertAdam Tolbert 

Repeated Apex calls from a helper.Js

Can someone please explain to me why the following code doesnt execute on its own?? It will only run one time and then requires a touch interaction on the screen to continue to run. Code works as expected if you rapidly click the screen, but hangs itself if the user doesnt click the page.
 
testFunction : function(component, token, tempSo) {
        var action = component.get("c.forLoopTest");
        
        action.setParams({
            "I": 5
        })
        console.log("I ran")
            action.setCallback(this, function(res) {
            

                console.log("Callback ran")
                console.log(res.getReturnValue())
                if(res.getReturnValue() < 20) {
                    setTimeout(() => {
                        console.log(res.getReturnValue());
                        action.setParams({
                            "I": (res.getReturnValue() + 1)
                        })
                        $A.enqueueAction(action)
  
                    }, 500)
                } else {
                    console.log("You did it!")
                }
        

        })
        $A.enqueueAction(action)

    },
 
Apex Controller class  

@AuraEnabled
    public static Integer forLoopTest(Integer I){
        Integer newI = I;
        return newI;
    }

 
Raj VakatiRaj Vakati
Use the Promise instead of time out like below 

Refer this link 
https://rajvakati.com/2018/05/29/using-promise-in-lightning-component/
var exeAction = component.get("c.executeMethod1");
 exeAction.setParams( {"message": 'Promise are cool way to handle callback'});
 helper.serverSideCall(component,exeAction).then(
 function(res) {
 var exeAction2 = component.get("c.executeMethod2");
 exeAction2.setParams( {"message": 'Promise are cool way to handle callback'});
 return helper.serverSideCall(component,exeAction2) ;
 
 }
 ).then(
 function(res) {
 var exeAction3 = component.get("c.executeMethod3");
 exeAction3.setParams( {"message": 'Promise are cool way to handle callback'});
 return helper.serverSideCall(component,exeAction3) ;
 }
 )
 .catch(
 function(error) {
 component.set("v.status" ,error ) ; 
 console.log(error);
 }
 );

 
Adam TolbertAdam Tolbert
@Raj, I can have the function promise until the end of time but the key issue im having here is that tI need to delay and then fire the action via a setTimeout or some other mechanism. I cannot have the function fire every chance it gets as the real world appllication is an API call that requires a query to know if it is done processing the previous step.

See main article here (https://developer.salesforce.com/forums/ForumsMain?id=9062I000000IIF3QAO) 

This was more of an abstraction of the above article wondering if there is an easwier way of queueing tasks within walesforce on a time delay in order to not overload our API daily budget with unecessary API calls as that can become quite expensive even if you were to have a smaller group of sales people, if it is making over 5 API calls a second and the response takes 15-20 seconds to return a positive result, with a salesforce fo 100 people using this feature 5 times a day, best case scenario, this one API call could be using 50,000 calls a day which can not only use a large portion of a daily limit, but can blow right through it in some cases.

Again, I can write seperate promises until the end of time but the main issue here is the setTimeout not firing the Apex action. Any further assistance would be greatly appreciated!
Adam TolbertAdam Tolbert
Ok so after some digging, and then some more digging I found this handy dandy function called $A.getCallback()

[https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_mod_ext_js.htm]

And this little gem is exactly waht I was looking for! The issue I was having was indeed a event loop /  Framework Lifecycle / callstack problem. I was actually able to prove that my code was indeed queueing the events into their stack but never executing them. This is because if you do something like a window.setTimeout(() => {logic}, 5000) that gets put onto another callstack outside of the main stack and the framework has no idea that it needs to execute it.

This $A.getcallback() allows the component to pull that event back into its own callstack and execute after the delay. Hoping this can save someone the time I lost here!
Adam TolbertAdam Tolbert
var seventhAction = component.get("c.iTechAPICall");
  seventhAction.setParams({
 "body": GetSalesOrderBody,
 "task": "GetSalesOrderDetails"
});
                                                    
seventhAction.setCallback(this, function(risposta) {
                                                    
const state = risposta.getState();
let res = risposta.getReturnValue();
console.log(state)
console.log(res)
if (res.includes("InProcess")) {
    
    console.log("Still Processing Order")
    window.setTimeout(
          $A.getCallback(function() {
                  $A.enqueueAction(seventhAction);
      }), 5000);

 } 

else { 
console.log("We did it!")
}

$A.enqueueAction(seventhAction);
See corrected code sample for reference