3

I ran into 2 problem with and afterScriptsLoaded. Have a sample component to bring list of contacts. on-load of the component I need to focus some div based on ID. Now the problem is, afterScriptsLoaded is behaving differently in different browsers.

Chrome - When freshly launched, I can see my code focusing the expected div. On pressing refresh(f5), the script fails to focus the div. On pressing cntrl+f5, again it starts working as expected.

Firefox and IE - All scenarios fails. afterScriptsLoaded is called properly but dont know why focus is not happening. I have tried latest and old version based on some answers i found on google and also tried to place the at the bottom of the component. Event tried changing the API version of the component to 39. still no luck.

<aura:component controller="NavigationController" access="GLOBAL">
<ltng:require scripts="{!$Resource.Jquery224}" afterScriptsLoaded="{!c.scriptsLoaded}" /> ==> Tried latest version and also the old versions. but no luck
<!-- NavigateAndFocusDetails -->
<aura:handler name="init" value="{!this}" action="{!c.onCompLoad}"/>
<aura:attribute name="Contacts" type="Object[]"/>   
    <div class="divCls">
            <aura:iteration items="{!v.Contacts}" var="con">
                <div id="{!con.Id}" tabindex='1' >                        
                    <span>{!con.FirstName}&nbsp;{!con.LastName}</span><br/>                        
                    <span>{!con.Account.Name }</span><br/>
                </div>
            </aura:iteration>
    </div>

Controller.js

    ({
    onCompLoad : function(component, event, helper) {
        //get all contacts from apex.
    },

    scriptsLoaded : function(comp,eve,help){        
        var divId ='#0036F00002mvuebQAA';
        $(divId).addClass("highlight");
        alert($(divId).length);     ==> On f5, this comes as 0 and when cntrl+f5, the value returns 1.   
    }
})

Tried adding $(divId).addClass("highlight"); also$(divId).focus(); Both acts same. enter image description here

1 Answer 1

4

Loading the scripts and getting the data from Apex are both async operations, so you've got a race condition between the two. Sometimes scriptsLoaded might get called before the Apex call in onCompLoad has finished.

So, you need to add some flags to control this e.g. a private attribute for scriptsLoadComplete and another one for contactLoadComplete. Then, have a helper method to do what you're doing in scriptsLoaded, but only when both of those flags are true. Finally, modify your scriptsLoaded, and onCompLoad to set the flags and call the helper function.

That way, it doesn't matter what order the race between async operations is resolved.

As for why you see different results in the scenarios you tried:

  • Different browsers will get different results with these race conditions.
  • ltng:require caches the scripts client-side. So, when you press reload, it doesn't load actually fetch it from the server. It already has it, so your scriptsLoaded function definitely wins the race in that case.
1
  • 1
    Want to comment because I ran into a similar situation and this ultimately fixed it; if you have multiple components doing gets and they don't all have this logic in them to mitigate the race conditions, if one fails they're ALL going to fail. I was dealing with this in Experience Builder, where in the Builder itself everything was fine, but if you went to the "live" page everything would work once then die on reload. Again, applying this fix to all components resolved the issue. I had to take them out and add them in (with one working one) one at a time to find this. Aug 5, 2021 at 14:07

You must log in to answer this question.

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