Passing Multiple Attributes to Application Type Event and Handling in Multiple Components – Lightning Aura

Here is what I am trying to do. I have components A, B, C all on the Home page and there is another component D which has few Aura:If blocks to display differnt blocks as needed.
I am using a few boolean attributes to render the Component D. When Someone clicks on Comp. A, I am firing an application event which sets the boolean value to True. and similar needs to happen for all the other components on the page. Bascially, instead of navigating the users away from the page, I am trying to show the data that they need in a split view. Hence multiple components will all render a section of component D depending on what was clicked.
Here is where I am stuck. EVen though I click on A, it shows me both AuraIf blocks, when debugging, the second aura If block is false but it still displays that block. Below is the code.

RenderDataEvent.evt

<aura:event type="APPLICATION" description="Event will be used to render other components on Home page">
    <aura:attribute name="showRenderA" type="Boolean" default="False"/>
    <aura:attribute name="showRenderB" type="Boolean" default="False"/>


</aura:event>

Cmp A has a link which has onclick which the controller is as below:

A.js

 renderA: function(component, event, helper){
        //Get the event using event name. 
        var appEvent = $A.get("e.c:HomeRenderData"); 
        //Set event attribute value
        appEvent.setParams({"showRenderA" : "True" ,
                            "showRenderB" : "False"}); 
        appEvent.fire(); 
    }

Cmp B.js

 renderB : function(component, event, helper){
        //Get the event using event name. 
        var appEvent = $A.get("e.c:HomeRenderData"); 
        //Set event attribute value
        appEvent.setParams({"showRenderB" : "True" ,
                            "showRenderA" : "False"}); 
        appEvent.fire(); 
    }

Finally this is the component wnere they are supposed to be rendered:

Comp D.cmp

<aura:attribute name="renderA" type="Boolean" default="False"/>
<aura:attribute name="renderB" type="Boolean" default="False"/>

        <aura:handler event="c:HomeRenderDataEvent" action="{!c.renderDataEvent}"/>
      
        <aura:renderIf isTrue="{!v.renderA}">
                       Display something ...
               
        </aura:renderIf>
        <aura:renderIf isTrue="{!v.renderB}">
                        Display something ...

        </aura:renderIf>

D.js

renderDataEvent : function(component, event, helper) {
        //Get the event attribute
        var A= event.getParam("A");
         var B= event.getParam("B");
        console.log("Event firing component"+event.getSource() );
        //set the handler attributes based on event data
        component.set("v.renderA", A);
        component.set("v.renderB", B);
        console.log('Render A '+component.get("v.renderA"));
        console.log('Render B '+component.get("v.renderB"));

    },

They both display even if I click on only one component.

Best Answer

Your code is using string values as if they were actual Boolean primitives:

    appEvent.setParams({"showRenderB" : "True" ,
                        "showRenderA" : "False"}); 

Because in JavaScript a non-empty String value is truthy, this results in your

    <aura:renderIf isTrue="{!v.renderA}">

evaluating to true: the string "False" is true, in this context. (Yes, it's very confusing to practitioners of strongly-typed languages!)

Fix: use actual primitive Boolean values:

    appEvent.setParams({"showRenderB" : true,
                        "showRenderA" : false}); 
Related Topic