14

I'd like to put some shared Javascript to Resource file to reuse it between several components. This Javascript is general purpose set of utility functions. However, functions from my resource file are not available from the Components. Static resource (named TestScript):

function helloWorld() {
     return 42;
}

Component:

<ltng:require scripts="{!$Resource.TestScript}"
<ui:button label="Do job" press="{!c.doJob}"/>

Controller:

doJob: function(cmp, event, helper) {
     var i = helloWorld();
     // failed with Uncaught ReferenceError: helloWorld is not defined
}

I don't like to use

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

because my static resource is a set of functions and I'd like just use them as functions later in my controllers. How can I achieve that (if possible)? If not, what's the suggested solution?

20

you could attach your utility methods to the global window object(SecureWindow) and use it in your controller.

Static Resource: TestScript

(function(w){
    "use strict"; //Optional because LC on LockerService active runs in strict mode

    var utilMethods = {
        "method1":method1,
        "method2":method2
    };

    function method1(){
        console.log("method1 called");
    } 

    function method2(){
        console.log("method2 called");
    }

    w.myUtil = utilMethods;

})(window);

Component:

<ltng:require scripts="{!$Resource.TestScript}" afterScriptsLoaded="{!c.afterScriptsLoaded}" />
<ui:button label="Do job" press="{!c.doJob}"/>

Controller.js:

doJob : function(cmp){
     myUtil.method1(); // Print method1 called
     myUtil.method2(); // Print method2 called
}
  • So I need to make changes in the static resource ? It doesn't make sense if I want to use external JS libraries. Do I need to change every function in the external library ? – osos9 Nov 26 '18 at 15:28
  • @osos9 Most of the common JS libraries available in the web exposes their public API using a similar approach. So you don't need to change their js file. But if you have js created to share its logic across the component then, you need to expose like above. – Praveen Nov 28 '18 at 7:32
2

Lightning is build around OOPs concepts.

Wiki for Object-oriented_programming

I was facing with same problem, I had some utility code which was getting repeated in my all components. In Agularjs for given problem we use services. You put your shared code there and simply all component can access your code.

In lightning we have helper you put your code there and all functions in controller within component can access that code. Problem it can't be access by other component.

If you are having strong oops background or coming with java background you know it's best practice to have base class called as BaseEntity (an abstract class) and all your other classes will extend this base class. This base class normally contains properties/methods which will be used in other class (e.g Id field)

So how this will solve your problem.

Create an abstract lightning component you may call it as BaseCmp. (as you know you can't directly utilize abstract components/classes)

for more refer to

So your basecmp will look like this

    <aura:component abstract="true" extensible="true">
        <aura:attribute name="yourCommonAttribute" type="String" />
        <ltng:require scripts="{!$Resource.resourceName}"/>
        <div>{!v.body}</div>
    </aura:component>

put your all static resources here if you think all components will require it.

Now coming to utility function part, write your all utility class in helper method. All components extending base cmp will get access to utility helper methods/ static resources. You can directly call all basecmp helper methods from your extended cmp. Don't write any controller method here as Lightning Components Developer Guide says:

We don't recommend using inheritance of client-side controllers as this feature may be deprecated in the future to preserve better component encapsulation. We recommend that you put common code in a helper instead.

Best part - your extended component can override these utility functions :)

May be for all - this is not the best solution. But I guess it's cleaner solution to given problem.

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.