Lightning Components executing logic on init state only

I want to detect whether a server feature is enabled in my component during init, set the response into a Boolean attribute, then, if so, not set that again.

This is with Platform Encryption. So technically the feature license can be provisioned, but not enabled as the org has not had a first Tenant Secret record generated.

So if the init query to populate the component data returns with no records, I know there is no TenantSecret record, Platform Encryption is not enabled, and my UI can respond.

If it is enabled, I set the flag to true, and never worry about it again in the component lifecycle.

Here’s the rub

The function I’m using to populate the data should work fine for refreshing data at other points in the component lifecycle. I don’t want to write one refresh function for init, and other for other times. But I’m having trouble detecting the “init” event in my controller/helper.

I’m using standard init event registration in the controller.

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

I would have expected to then be able to detect this is the init event as below in my controller, but all the pertinent calls return undefined or information that is not useful:

doInit : function(component, event, helper) {
  console.log(event.getName()); //Undefined
  console.log(event.getParams()); //returns only instance of component
  console.log(event.getSource()); //tried this just for giggles, but also undefined

So if I want to run some code in a reusable method only during the init cycle and ignore it at all other times, how do I do this?

(I have found a workaround, but will wait and see what people come back with.)

Answer

My workaround basically consists of tracking the init state on the component.

So in my init handler I’m doing this:

doInit : function(component, event, helper) {
  component.isInit = true; 
  helper.fetchComponentData(component, event);

The tricky part that I’m not satisfied with is how to get the the flag to be unset at the right time. At first glance this might look good:

doInit : function(component, event, helper) {
  component.isInit = true; 
  helper.fetchComponentData(component, event);
  component.isInit = false; 
}

But fetchComponentData is firing off server actions that get queued up, so they end up completing after component.isInit = false; actually happens. This probably doesn’t surprise many of you, but maybe a few people will read that and have an ah-hah moment.

I was hoping using setTimeout might push function to the bottom of the event queue that would end up firing after the response from my server call, so I tried this:

doInit : function(component, event, helper) {
  component.isInit = true; 
  helper.fetchComponentData(component, event);

  window.setTimeout(
    $A.getCallback(function(){
      component.isInit = false;
    }),1000                 //also tried with 1, but that didn't work
  );                        
}

This works, but I don’t like there to be some arbitrary 1000ms delay that hopefully ends up being after my server callback.

The most predictable, I think, ends up being to put component.isInit = false as the last thing that my server callback does. But if the internal mechanics of the fetchComponentData function ever change, it could lead to unpredictable results.

This last option is what I have chosen for now. Ideally, I would like the framework to be able to tell me when init has been triggered, and automatically, once all enqueued actions have finished their callbacks, set it to false. But I don’t see a better way to do it for now.

Attribution
Source : Link , Question Author : pchittum , Answer Author : pchittum

Leave a Comment