5

I have multiple Helper functions, like fetching User Name, partnerURL and Session Id and then I want to use the attributes used in these helpers in a single controller function, what is the best way to achieve this, like have a single helper or let it be multiple helpers,

Helper looks like this:

getUserName : function(component, event, helper) {

    //loading user related data
    var action = component.get("c.getUserName");
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            component.set("v.Name", response.getReturnValue());
         }
    });
    $A.enqueueAction(action);   
},

getOrgId : function(component, event, helper) {
    //get org Id
    var action = component.get("c.getOrgId");
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            component.set("v.OrgId", response.getReturnValue());
         }
    });
    $A.enqueueAction(action);
},

partnerURL : function(component, event, helper) {
    //get partnerURL
    var action = component.get("c.partnerURL");
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            component.set("v.partnerURL", response.getReturnValue());
         }
    });
    $A.enqueueAction(action);
},

Controller :

doinit : function(component, event, helper) {

    helper.orgId(component);
    helper.partnerURL(component);
    helper.sessionId(component);

   //Now here I want to use the attributes used in above helpers
   // like below 
  var TEST = component.get("v.Name") + ' ' component.get("v.partnerURL");
}
5

There is no reason for doing multiple requests to get the data from the server which can be done in a single request.

There is one more issue in the following statement i.e. You may get undefined values for(var TEST = component.get("v.Name") + ' ' component.get("v.partnerURL")) as we are executing this statement just after making an Ajax request and Ajax requests are Asynchronous (don't block):

doinit : function(component, event, helper) {
    helper.orgId(component);
    helper.partnerURL(component);
    helper.sessionId(component);

   //Now here I want to use the attributes used in above helpers
   // like below 
   /* This statement may execute before we get the response from the server. */
   var TEST = component.get("v.Name") + ' ' component.get("v.partnerURL");
}

Here is the full code with the Ajax issue fix and single request to get settings from the server:

Apex

public class Apex {

    @AuraEnabled
    public static Map<String, String> getSettings(){        
        Map<String, String> data = new Map<String, String>();

        data.put('userId', UserInfo.getUserId());
        data.put('orgId', UserInfo.getOrganizationId());        
        data.put('partnerURL', URL.getSalesforceBaseUrl().toExternalForm() + '/services/Soap/u/28.0/' + UserInfo.getOrganizationId());
        return data;
    }

}

Component

<aura:component controller="Apex">
    <aura:handler name="init" value="{!this}" action="{!c.init}"/>

    <aura:attribute name="settings" type="Map" default="{}" />    
</aura:component>

Controller

({
    init : function(c, e, h) {
        h.getSettings(c, function(){
            var settings = c.get("v.settings");
            console.log('settings: ', settings);
            var loadedData = settings.userId + ' ' + settings.partnerURL;
            console.log('loadedData: ' + loadedData);
        });
    }
})

Helper

({
    getSettings : function(c, cb) {        
        var a = c.get("c.getSettings");
        a.setCallback(this, function(r){
            var s = r.getState();

            if (s === "SUCCESS") {
                var settings = r.getReturnValue();
                c.set("v.settings", settings);

                if(cb){
                    cb();
                }                
            }
        });
        $A.enqueueAction(a);
    }
})
  • 2
    The way you utilized the map and extract the value out from it in helper is really a good to way to minimize many helpers to fetch values. Thank you – Abhi Tripathi May 2 '17 at 17:03
  • Yes, if we use Map we don't need to create a Wrapper class; – itzmukeshy7 May 2 '17 at 18:01
1

There are multiple ways to solve the problem where you need to access multiple methods

Optimize it to ServerSide

In this pattern you will create an apex wrapper class/Map that can contain all the variables you need

@AuraEnabled
public static UserInfoWrapper getUsetInfo(){
    String partnerurl = URL.getSalesforceBaseUrl().toExternalForm() + '/services/Soap/u/28.0/' + UserInfo.getOrganizationId();
    UserInfoWrapper userinfowrap = new UserInfoWrapper(userinfo.getUserId(),Userinfo.getOrganizationId(),partnerurl);
  return userinfowrap;
}

//Wrapper apex class

public class UserInfoWrapper {
@AuraEnabled
 public String orgId;
 @AuraEnabled
 public String userId;
 @AuraEnabled
 public String partnerurl;
    public UserInfoWrapper(String userId,String orgId,String partnerurl){
       this.userId = userId;
       this.orgId = orgId;
       this.partnerurl = partnerurl;
    }
}

Most of times Server Side optimization is really amazing way to get all the data you need unless you are running into CPU limits due to large number describe calls or number of SOQLS is exceeded .

Now you can use the callback mechanisms to access these attributes in your controller from single helper .

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.