2

I am new to Aura, and I am stuck on how to proceed with the task given. Actually, in the Init method, there are many chaining that should be optimized.

My controller class

doInit: function (component, event, helper) {
helper.getMetadata(component, event, helper)
  .then(function () {
    return helper.getUserInfo(component, event, helper);
  })
  .then(function () {
    return helper.getContactInfo(component, event, helper);
  })
  .then(function () {
    return helper.getIPAddress(component, event, helper);
  })
  .then(.... //Truncated for the brevity
  .catch(function (error) {
    helper.showError(component, event, helper, error);
    let spinner = component.find("spinner");
    $A.util.addClass(spinner, "slds-hide");
  });

My helper class:

    getMetadata: function(component, event, helper) {
    var self = this;
    return new Promise(
      $A.getCallback(function(resolve, reject) {
        var action = component.get("c.getMetadata");
        action.setCallback(this, function(response) {
          var errors = response.getError();
          if (errors) {
            if (errors[0] && errors[0].message) {
              helper.showError(component, event, helper, errors[0].message);
            }
          }
          var state = response.getState();
          if (state === "SUCCESS") {
            var response = response.getReturnValue();
            var wrapper = JSON.parse(response);
            component.set("v.webCaseWrapper", wrapper);
            resolve();
          } else {
            reject($A.get("$Label.c.cs_get_metadata_error"));
          }
        });
        $A.enqueueAction(action);
      })
    );
  },

    getUserInfo: function(component, event, helper) {
    return new Promise(
      $A.getCallback(function(resolve, reject) {
        var runningUserId = component.get("v.runningUserId");
        if (runningUserId && runningUserId != "0051U000000sBUGQA2") {
          var action = component.get("c.getUserInfo");
          action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
              var response = response.getReturnValue();
              component.set("v.name", user.Name);
              component.set("v.email", user.Contact.Email);
              }
              resolve();
            } else {
              reject($A.get("$Label.c.cs_get_user_info_error"));
            }
          });
          $A.enqueueAction(action);
        } else {
          resolve();
        }
      })
    );
  },
 //Similar functions for getIPAddress, getContactInfo

How do I reduce the number of chaining in CONTROLLER js

2
  • 1
    It would be a better investment of your time to port the component to LWC and use modern async/await syntax.
    – David Reed
    Commented Jan 9, 2022 at 17:08
  • 1
    @DavidReed Unless it's an App, or isn't supported for a given use case, etc... There's still plenty of reasons why you'd need Aura.
    – sfdcfox
    Commented Jan 9, 2022 at 17:52

1 Answer 1

3

You don't need to chain most of the methods, because they're independent. Aura is perfectly capable of calling many different methods at once. As such, you can use Promise.all to call the methods. It looks like the first method will inform the later methods of what they should do, so you can:

doInit: function (component, event, helper) {
    helper
    .getMetadata(component, event, helper)
    .then(() =>
        Promise.all([
        helper.getUserInfo(component, event, helper),
        helper.getContactInfo(component, event, helper),
        helper.getIPAddress(component, event, helper),
        ])
    )
    .then(function (results) {
        // Do stuff here
    })
    .catch(function (error) {
        helper.showError(component, event, helper, error);
    })
    .finally(function () {
        let spinner = component.find("spinner");
        $A.util.addClass(spinner, "slds-hide");
    });
}

If I've misread anything, and they're all really independent calls, you can just put them all in Promise.all:

doInit: function (component, event, helper) {
    Promise.all([
    helper.getMetadata(component, event, helper),
    helper.getUserInfo(component, event, helper),
    helper.getContactInfo(component, event, helper),
    helper.getIPAddress(component, event, helper),
    ])
    .then(function (results) {
        // Do stuff here
    })
    .catch(function (error) {
        helper.showError(component, event, helper, error);
    })
    .finally(function () {
        let spinner = component.find("spinner");
        $A.util.addClass(spinner, "slds-hide");
    });
}

Also, as demonstrated in this answer, you can use arrow functions to make things more legible. If you still wanted to call the methods one after the other, you could:

helper.getMetadata(component, event, helper)
  .then(() => helper.getUserInfo(component, event, helper))
  .then(() => helper.getContactInfo(component, event, helper))
  .then(() => helper.getIPAddress(component, event, helper));

Which is far easier to read than the original version.

You must log in to answer this question.

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