I'm having trouble accessing my static resource (a js lib) in my controller.js in my lightning component.
My goal is to bundle up all my javascript functions and classes and use across most components, and NOT paste them in the helper.js everytime!
in static resource (BaseFunctions / public / application/javascript)
window.BaseFunctions = (function() {
var _toast = function (type, title, message, data) {
let params = {
'mode': 'dismissible',
'duration': '5000'
};
if (type === 'info' || !type) {
params.title = title || 'Info';
params.key = 'info_alt'; // or info
params.type = 'info';
} else if (type === 'success') {
params.title = title || 'Success';
params.key = params.type = 'success';
} else if (type === 'warning') {
params.title = title || 'Warning';
params.key = params.type = 'warning';
} else if (type === 'error') {
params.title = title || 'Error';
params.key = params.type = 'error';
}
if (Array.isArray(data)) {
params.messageTemplate = message;
params.messageTemplateData = data;
} else {
params.message = message;
}
$A.get('e.force:showToast').setParams(params).fire();
};
var _refreshView = function () {
$A.get('e.force:refreshView').fire();
};
var _closeQuickAction = function () {
$A.get('e.force:closeQuickAction').fire();
};
return {
toast: _toast,
closeQuickAction: _closeQuickAction,
refreshView: _refreshView
};
}());
in .cmp file
<ltng:require scripts="{!$Resource.BaseFunctions}" />
in controller.js / init function
BaseFunctions // this is undefined!
// this obviously also crashes the component
BaseFunctions.toast('info', null, 'test message');
The ugly solution:
This is tested and gives result.
added this to .cmp
<aura:attribute name="templateLoaded" type="Boolean" default="false" />
<aura:attribute name="scriptsLoaded" type="Boolean" default="false" />
<!-- already had these 2, for anyone who needs the full code -->
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<ltng:require scripts="{!$Resource.BaseFunctions}" afterScriptsLoaded="{!c.afterScriptsLoaded}"/>
and in the controller.js
doInit: function (component, event, helper) {
component.set('v.templateLoaded', true);
$A.enqueueAction(component.get('c.fullLoadCheck'));
},
afterScriptsLoaded: function(component, event, helper) {
component.set('v.scriptsLoaded', true);
$A.enqueueAction(component.get('c.fullLoadCheck'));
},
fullLoadCheck: function(component, event, helper) {
if (component.get('v.templateLoaded') && component.get('v.scriptsLoaded')) {
$A.enqueueAction(component.get('c.realInit'));
}
},
// real init. template and the static js-libs loaded.
realInit: function(component, event, helper) {
console.log('realInit');
BaseFunctions.toast('success', null, 'it worked');
},
Best Answer
Your scripts from
<ltng:require>
are not guaranteed to be available in your component'sinit
handler. They are loaded asynchronously. You need to add the attributeto your
<ltng:require>
tag, and implement aafterScriptsLoaded
handler function in your component controller to take any actions that are required when your script library becomes available to the component.See Using External JavaScript Libraries :