0

I am working on a lightning component where I want to load resources then, an action function, then resources, then action function. I currently have the component set up like this:

<ltng:require styles="{!join(',', 
        $Resource.bootstrap3 + '/css/bootstrap.min.css', 
        $Resource.customCSS,
        $Resource.lightgallery + '/lightgallery/css/lightgallery.css',
        $Resource.SLDS100 + '/assets/styles/salesforce-lightning-design-system-vf.css')}"
      afterScriptsLoaded="{!c.loadSfEnv}"/>

<!-- 60 lines of html -->

<ltng:require scripts="{!$Resource.myCustomAppBundle_js}"
    afterScriptsLoaded="{!c.loadCustomApp}"/>

The c.loadSfEnv has an apex callback in it that gets data needed in the $Resource.myCustomAppBundle_js, which loads code needed in the c.loadCustomApp. The c.loadCustomApp action function also has apex calls in it and so its javascript can't be added to the $Resource.myCustomAppBundle_js. Most of the time the way of doing it above works because because the c.loadSfEnv callback is finished before $Resource.myCustomAppBundle_js loads but occasionally it doesn't load it in time and the page breaks.

Is there a way to ensure that $Resource.myCustomAppBundle_js is loaded only after the callback in c.loadSfEnv has completed? I've tried things like this below but it doesn't work.

 <ltng:require scripts="{!join(',',
        c.loadSfEnv, 
        $Resource.formDisplayAppBundle_js)}"
    afterScriptsLoaded="{!c.loadForm}"/>

Update: An alternate solution would be to load the $Resource.formDisplayAppBundle_js in the callback of the c.loadSfEnv but I didn't know if that was possible.

  • 1
    why not have just one ltng:require and call c.loadSfEnv then call helper's loadCustomApp() method? – Praveen Sep 11 '16 at 8:43
  • I'm not sure if I exactly understand what you are suggesting here but the order of loading is what's important here. It needs to be the c.loadSfEnv method, then the $Resource, then the c.loadForm method in that order, once the call backs are done. Both those methods are in the js controller. Another option would be to load the static resource from the controller but I didn't think that was possible. – Rozgonyi Sep 12 '16 at 13:38
0

Ok, so I figured this out, with a hint from this blog post. My c.loadSfEnv is now patterned like this with the static resource load and the contents c.loadForm added to it as part of its internal callback chain:

window.sfEnv = {};

let getInitInfo = cmp.get("c.getInitInfo");

getInitInfo.setCallback(this, function(response) {
    let state = response.getState()
    if (response.getState() === "SUCCESS") {
        let info = JSON.parse(response.getReturnValue());

        sfEnv.countryPicklists = info.countryPicklistsEnabled;
        sfEnv.namespace = info.namespace;
        cmp.set('v.namespace',info.namespace);

        //Then load App Static Resource so its methods can be used later
        var loadScript = document.createElement('script');
        loadScript.setAttribute('src', '/resource/myCustomAppBundle_js');
        document.head.appendChild(loadScript);

        //This was initially called in c.loadCustomApp
        let getMoreFromApex = cmp.get("c.getMoreFromApex");
        getMoreFromApex.setCallback(this, function(response){
            if (response.getState() === "SUCCESS") {
                let myData = JSON.parse(response.getReturnValue());
                window.methodCreatedInStaticRes(myData);
            }
        });

        $A.enqueueAction(getMoreFromApex);
    }
});

$A.enqueueAction(getInitInfo);

Then on the page I just have this at the bottom since the static resource app references a div in the component html:

<ltng:require scripts=""
    afterScriptsLoaded="{!c.loadSfEnv}"/>
  • why do you want to call getMoreFromApex again after sfEnv is set? – Praveen Sep 12 '16 at 19:30
  • why not have <ltng:require scripts="{!$Resource.myCustomAppBundle_js}" afterScriptsLoaded="{!c.loadSfEnv}"/>.So first loadSfEnv will be called followed by getMoreFromApex() method and finally methodCreatedInStaticRes() – Praveen Sep 12 '16 at 19:47
  • I'm calling c.getMoreFromApex after the bundle because I need different things at different times in that order. The root issue is that I was trying to port a JQuery app designed for a VisualForce page into a Lightning Component while only re-writing a minimal amount of code and not loosing the VisualForce compatibility. The JQuery app has VisualForce Remoting throughout it that I had to bypass and replace with callbacks in the lightning component js controller. Were it greenfield, I would've put more code into the lightning js controller/helper to avoid this but that wasn't possible. – Rozgonyi Sep 13 '16 at 13:13
  • Ok I got your point.If the answer solves the problem, please mark it as accepted. – Praveen Sep 13 '16 at 14:01

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.