In my Lightning components I always find logging and remembering how to navigate to urls using events to be an issue so I wrote this small utility base component that I then extend when creating new components. The base component share its helper with the subcomponents which allows for easy reuse of the utility functionality. The utility code provides both logging and various other utility functions such as navigating to other objects, presenting toasts etc.
Component definition of the base component is simple (note the {!v.body} which is key for abstract components to make sure the markup of child components appear):
<aura:component abstract="true" extensible="true"> <aura:handler name="init" value="{!this}" action="{!c.doinit}" /> {!v.body} </aura:component>
Controller is likewise simple with basically only a callout to the helper to initialize a named Logger instance and store it in a variable called logger in the helper.
({ doinit: function(component, event, helper) { const logger = helper.getLogger('SFLC_LightningHelper'); logger.trace('Initializing LightningHelper'); helper.logger = logger; } })
To use it from another component you first extend the base component:
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" extends="c:BaseComponent" controller="Foo_LCC"> <aura:attribute name="recordId" type="Id" /> <aura:handler name="init" value="{!this}" action="{!c.doinit}" /> ... ... </aura:component>
Then in the component controller initialization event create a named utility object (actually names the logger) and store it the “util” variable in the helper making it accessible using helper.util and the logger using helper.util.logger.
({ doinit: function(component, event, helper) { // build utility const utility = helper.buildUtilityObject('MyComponent'); helper.util = utility; // load data helper.loadData(component); } })
From here on out you can simply use helper.util.logger.info, helper.util.logger.debug etc. to log for the component. All log messages are output using the named logger. The log level which by default is NONE (meaning no output is output) is controllable using a URL parameter and loggers may be turned on and off using a URL parameter as well. Please note that the URL format used here doesn’t live up to the changes coming to Lightning URL’s in Summer ’18 or Winter ’18 (cannot remember which release).
Using the utility functionality can be done from controller and helper as shown in the loadData method using both utility functionality to invoke a remote action and to log:
({ loadData: function(component) { // load data const helper = this; helper.util.invokeRemoteAction(component, 'getData', {'recordId': component.get("v.recordId")}, function(err, data) { if (err) { helper.util.toast.error('Data Load Error', 'Unable to load data from server ('+ err +'). If the issue persists contact your System Administrator.', {sticky: true}); return; } helper.util.log.debug('Received data from endpoint', data); } ) } })
Zip file with Controller and Helper: BaseComponent
Great stuff Mikkel. Only side effect using Extending is that you can only do it once for a component. Other than that, nice base framework. Will look to hook it up with Bugsnag.
LikeLike
Yeah looked at bugsnag yesterday after you mentioned it. Looks very nice although I couldn’t really find a nice example beyond the simple videos they have. And totally agree on the extend thing – having a mixin/multiple inheritance really shines for that. An alternative is to keep the utils as a static resource but then maintaining becomes a bit harder.
LikeLike