0

I want to load my static resources before my event is fired. My scripts are not getting loaded and my jquery builder gives function not defined. My event is application event. So my query builder gives $j(...).queryBuilder is not a function error

My code is:

CategoryBuilder.Cmp

<aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,force:hasRecordId" access="global" controller="BRCategoryCtrl" >
          <c:BRCreateQueryBuilder wrapperBlock="{!wblock}" index="{!indexBlock}"        
             columnDetailsresponse="{!v.columnDetailsresponse}"/>
<aura:registerEvent name="createBlock" type="c:BRCreateBlock"/>
</aura:component >

CategoryBuilder.js

generateEvent:function(component, event, helper){
var genrateEvent = $A.get("e.c:BRCreateBlock");
genrateEvent.setParams({"dataindex" : '1'});               
genrateEvent.fire();
}

Code for c:BRCreateQueryBuilder:

<aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,force:hasRecordId" access="global" controller="BRCategoryCtrl">
<ltng:require scripts="{!join(',',$Resource.JQuery244 + '/jquery-2.2.4.min.js',$Resource.QueryBuilderStandaloneMin + '/query-builder.standalone.min.js',$Resource.CPGCommonScript,$Resource.Select2 + '/select2-4.0.3/dist/js/select2.js')}" styles="{!join(',',$Resource.QueryBuildCSS + '/query-builder.default.min.css',$Resource.BootCSS + '/bootstrap.min.css', $Resource.Select2 + '/select2-4.0.3/dist/css/select2.min.css')}"  afterScriptsLoaded="{!c.afterloadscript}" />
 <aura:handler event="c:BRCreateBlock" action="{!c.handleAddGroup}" />
     </aura:component >

Controller

handleAddGroup:function(component,event,helper){
             console.log("Add group");
             component.getBuilderData();
},
getBuilderData : function(component,event,helper){
            var $j = jQuery.noConflict();
            console.log('in get builder');
            var filterJson = [];
            var columnDetails = component.get('v.columnDetailsresponse');
            for(var i=0;i<columnDetails.length;i++){
             if(columnDetails[i].datatype__c=='Numeric'){
            filterJson.push({id:"'"+columnDetails[i].tb_col_nm__c+ "'",label:columnDetails[i].tb_col_nm__c,type:'integer',input: 'select',operators: ['equal', 'not_equal', 'in', 'not_in', 'is_null', 'is_not_null','less','less_or_equal','greater','greater_or_equal'],values:{1:'1',2:'2'}});
          }else{
              filterJson.push({id:"'"+columnDetails[i].tb_col_nm__c+ "'",label:columnDetails[i].tb_col_nm__c,type:'string',operators: ['equal', 'not_equal', 'in', 'not_in', 'is_null', 'is_not_null'],value:{}});
          }

       }
        console.log('**JSON**');
        console.log(filterJson);
        $j('#group_0').queryBuilder({
           filters: filterJson,
         // rules: rules_basic
        }); 
},
3
  • 1
    Where is the event c:BRCreateBlock being fired? That seems to be your issue, since its handler is the only place in the code you've shared where you call getBuilderData(). Also, please make an effort to format your code cleanly so it can be read.
    – David Reed
    Jan 20 '18 at 14:14
  • I edited the code. Event is fired by CategoryBuilder component mentioned above.
    – Jill_sfdc
    Jan 20 '18 at 16:00
  • 1
    There's still not enough information here to trace the call sequence. I see that CategoryBuilder.generateEvent() fires c:BRCreateBlock, which is handled by BRCreateQueryBuilder.handleAddGroup(), which calls getBuilderData(), which throws an error. But the important question here is where does this call sequence start, and why is it happening before your <ltng:require> finishes loading? Since we can't see where generateEvent() is called from, you'll have to do some more work to pin that down, but that's where you'll find the solution.
    – David Reed
    Jan 21 '18 at 13:19
0

I don't know why you are not using afterScriptsLoaded() method. Also, this is assuming that generateEvent() is getting called so quickly that scripts are not yet loaded.

You can add a flag after which your app event will fire and this flag will become true when afterScriptsLoaded() executes, i.e when all scripts are loaded. This attribute has a change event written on it and its onchange action will call generateEvent().

Alternatively, you can send event from child to parent to notify loading of scripts.

You can do something like:

CategoryBuilder.Cmp

<aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,force:hasRecordId" access="global" controller="BRCategoryCtrl" >
    <!--Add a attribute that is passed to child component. Change in this attribute in child will reflect in parent component as well, triggering the on change event-->
    <aura:attribute name="isScriptsLoaded" type="Boolean" default="false" />

    <c:BRCreateQueryBuilder wrapperBlock="{!wblock}" index="{!indexBlock}"        
    columnDetailsresponse="{!v.columnDetailsresponse}" isScriptsLoaded="
    {!v.isScriptsLoaded}"/>

    <aura:registerEvent name="createBlock" type="c:BRCreateBlock"/>
    <aura:handler name="change" value="{!v.isScriptsLoaded}" action="{!c.generateEvent}" />
</aura:component >

Code for c:BRCreateQueryBuilder:

<aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,force:hasRecordId" access="global" controller="BRCategoryCtrl">
  <ltng:require scripts="{!join(',',$Resource.JQuery244 + '/jquery-2.2.4.min.js',$Resource.QueryBuilderStandaloneMin + '/query-builder.standalone.min.js',$Resource.CPGCommonScript,$Resource.Select2 + '/select2-4.0.3/dist/js/select2.js')}" styles="{!join(',',$Resource.QueryBuildCSS + '/query-builder.default.min.css',$Resource.BootCSS + '/bootstrap.min.css', $Resource.Select2 + '/select2-4.0.3/dist/css/select2.min.css')}"  afterScriptsLoaded="{!c.afterloadscript}" />

<aura:attribute name="isScriptsLoaded" type="Boolean" default="false" />

  <aura:handler event="c:BRCreateBlock" action="{!c.handleAddGroup}" />

Controller

   afterloadscript : function(component, event, helper){
          //This will set isScriptsLoaded true in parent as well.
          component.set('v.isScriptsLoaded', true);

          /*Alternatively you can also send component event from here to parent.*/
   }

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.