2

I am doing polling in my Lightning Component using setTimeout and $A.getCallback but the callback is called 3 times in a row at the next tick.

Controller.js:

  // Fired one time at component creation
  doInit : function(component, event, helper) {
    helper.mainAction(component);
  }

Helper.js:

mainAction: function(component) {
    const recordId    = component.get("v.recordId");
    const sObjectName = component.get('v.sObjectName');
    const action      = component.get("c.doAction");

    action.setParams({
      sObjectName: sObjectName,
      recordId: recordId
    });

    action.setCallback(this, response => {

      const state = response.getState();

      if (state === "SUCCESS") {
        const response = response.getReturnValue();
        console.log('sobj found:', response);
        // do stuff
      } else { // do stuff }

      setTimeout($A.getCallback(() => this.mainAction(component)), 5000);
    });

    $A.enqueueAction(action);
}

3 times in a row

The required flow is:

  1. DoInit (init handler)
  2. Fetching data
  3. Fetching data

    .

    .

    n. Same action as n-1

8
  • Shouldn't this line () => this.mainAction(component) be () => { this.mainAction(component);} (I could easily be wrong - I don't know much about ES6 Syntax) Jul 12, 2017 at 7:49
  • 1
    Is the "this" in your $A.getCallback definitely the helper object still? I usually assign this to some variable in the outer scope to ensure I'm still using what I want Jul 12, 2017 at 7:52
  • 1
    ... and according to Compatibility section of the answer here => is not supported in e.g. IE11. Safer to use the better known function syntax.
    – Keith C
    Jul 12, 2017 at 7:53
  • Indeed it defines the helper, but we are in a lambda function (@Caspar) , the context is preserved (@MatthGoldspink). developer.mozilla.org/en/docs/Web/JavaScript/Reference/… "An arrow function does not create its own this, the this value of the enclosing execution context is used."
    – Simonp
    Jul 12, 2017 at 7:54
  • @MattGoldspink this syntax does not create a new this scope, so this is fine Jul 12, 2017 at 7:54

1 Answer 1

4

Fixed by sending the data in the recursion instead of getting the information from component:

Controller.js:

  // Fired one time at component creation
  doInit : function(component, event, helper) {
    const recordId    = component.get("v.recordId");
    const sObjectName = component.get('v.sObjectName');
    helper.mainAction(component, recordId, sObjectName);
  }

Helper.js:

mainAction: function(component, recordId, sObjectName) {
    const action      = component.get("c.doAction");

    action.setParams({
      sObjectName: sObjectName,
      recordId: recordId
    });

    action.setCallback(this, response => {

      const state = response.getState();

      if (state === "SUCCESS") {
        const response = response.getReturnValue();
        console.log('sobj found:', response);
        // do stuff
      } else { // do stuff }

      setTimeout($A.getCallback(() => this.mainAction(component, recordId, sObjectName)), 5000);
    });

    $A.enqueueAction(action);
}
3
  • Good to know. I was able to make the issue go away by putting setTimeout as the first statement in the setCallback function. Jul 12, 2017 at 8:22
  • 1
    Although I had a different issue. Probably caused by something similar though - component validity, storing of actions etc Jul 12, 2017 at 8:22
  • Another issue popping from this behaviour is when the polling is fired and you browse to another record page WHERE THE LIGHTNING COMPONENT IS NOT PRESENT, this JS behaviour is still working in back (cf. browser developer console network): Salesforce does not unmount/delete the component...
    – Simonp
    Jul 12, 2017 at 9:23

You must log in to answer this question.

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