5

The Goal

I am trying to conditionally render a component after a user successfully uploads a CSV file. Here is the markup for the conditional rendering. Details have been omitted:

<!-- Create boolean attribute and set default to false -->
<aura:attribute name="hasParsedCSV" type="Boolean" default="false" />

<!-- If attribute is false, display main content -->
<aura:if isTrue="{!v.hasParsedCSV == false}">
    <!-- Internal details omitted ... -->
    <!-- The file upload starts with the input tag below. -->
    <input type="file" accept=".csv" onchange="{!c.onCSVFileSelect}" />
</aura:if>

<!-- After a successful upload/parse, the attribute should be set to true. -->
<aura:if isTrue="{!v.hasParsedCSV}">
    <!-- Internal details omitted ... it renders a new component. -->
</aura:if>

So far the logic seems fairly simple:

  • The user first hits the page, and the main content is displayed. The user can select a CSV file to import.
  • When a user successfully uploads a file, the hasParsedCSV will be set to true.
  • Once hasParsedCSV is true, the component will re-render and display only what is inside the isTrue="{!v.hasParsedCSV}.

The Problem

The problem occurs when I try to set the value of the hasParsedCSV attribute. I know it properly sets the value to true, but when the component rerenders it loses its value and is set back to false. Take a look at the controller code. Again, some details have been omitted:

let fileInputElement = component.find('csv-upload').getElement();

// User cancelled file upload operation.
if(fileInputElement.files[0] === undefined) {
    return;
}

let csvFile = fileInputElement.files[0];
helper.handleCSVFileUpload(component, helper, csvFile)
.then($A.getCallback(function(contactList) {

    // Once these attributes are set, the conditional component should render
    component.set("v.hasParsedCSV", true);

    // console.log('hasParsedCSV?:  ' + component.get('v.hasParsedCSV'));
    // debugger;

}))
.catch(function(error){
    helper.setErrorAndShowMessage(component, error);
});

I've commented out a few debug logs and the use of debugger. I've confirmed that the component attributes are successfully updated with the proper values.

However after the execution of the resolve callback, the component is re-rendered back to its original values (i.e., hasParsedCSV is set to false, and the conditional component does not render).


The Question

Has anyone had problems with this before? My Promise resolve callback is setting component values but once the component re-renders (i.e., once I execute component.set()) I lose the value.

I appreciate any help.


Updated Notes

12:15pm:

I have added a doInit event handler to check the Global ID of my component. I've discovered the doInit fires twice (once at the beginning of a page load, and another during a successful parse of my CSV file).

This is the reason why the attribute values are reset, but I am not sure why doInit would fire twice. I thought component.set(...) re-renders the component, and not completely initializes a new one.

  • What do you mean by "re-render the component"? I don't see in your code how you do that. – Charles T Aug 24 '18 at 19:18
  • @CharlesT Sorry for the confusion, when I say "re-render the component" I mean I am using component.set(). It's my understanding calling this function will automatically re-render the component to reflect any changed values. – Salesforce_Noobie Aug 24 '18 at 19:19
  • @Salesforce_Noobie Is there a gist somewhere where we can reproduce it . Also use the set function in the helper and enqueue the action . – Mohith Shrivastava Aug 24 '18 at 21:01
3

Solution

I am a fool. There was nothing wrong with my Promises or their resolve callbacks. The conditional component I was rendering would automatically redirect the page back to the original component.

In other words, any time I thought I was rendering the conditional child component, it would immediately instantiate a new parent. Hence why my attributes were reset.

I have fixed the conditional child component and everything works fine.

Pro tip: If you ever execute logic depending on what's in your URL, don't forget to make sure the values are properly set! Otherwise you'll have my issue.

Thanks for those who asked questions and took the time to read this. I am the true Salesforce_Noobie.

  • "I am a fool." :hahaha: --> you are not, you tried, you bashed your head against the wall, you prevailed. thanks for posting the solution. +1, and happy coding! – glls Aug 25 '18 at 0:45

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.