1

I have two Components ComponentA, and ComponentB, I have an Event, I have put my component in my App. Like below

App:

<aura:application >
    <ComponentA />
    <ComponentB chartName="BarChart" chartData="BarChartData" />
</aura:application>  

I am trying to trigger (call) ComponentA's createChart function when I click on ComponentB's Button, but the function isn't firing.

Event

<aura:event type="APPLICATION" description="Event template">
    <aura:attribute name="chartName" default="BarChart" type="String" access="global" />
    <aura:attribute name="chartData" default="BarChartData" type="String" access="global" />
</aura:event>  

Event Registration in ComponentB

<aura:registerEvent name="creatChart" type="c:CreatChartEvent"/>  

ComponentB Button Click Handler

buttonClick: function(component, event, helper) {
        debugger // on button click it hits this debugger

        var selectedChart = "BarChart";
        var creatChartEvent = $A.get("event.c:CreatChartEvent");
        creatChartEvent.setParams({ "chartName": selectedChart, "chartDataProviderName" :  selectedChart+"Data"});
        creatChartEvent.fire();  

// I have also tried  
//   var creatChartEvent = component.getEvent("c:CreatChartEvent");  
//   creatChartEvent.setParams({ "chartName": selectedChart,   "chartDataProviderName" :  selectedChart+"Data"});
//   creatChartEvent.fire();

    }  

Event Handler in ComponentA

<aura:handler name="creatChart" event="c:CreatChartEvent" action="{!c.creatChart}" />  

ComponentA creatChart function

creatChart : function(component, event, helper){
        debugger // does not hit this debugger

        alert("in componentA creatChart");
    }
  • 1
    can you try removing the name="creatChart" in the aura:handler of componentA?. Since the c:CreatChartEvent being the Application Event, they do not require name attribute specified in the handler. – Praveen Mar 8 '17 at 10:37
  • on reviewing the docs, I you're right @Praveen. I wonder if there's an order of precedence or something, if name is supplied, use that - if not, use the event type? – Phil Hawthorn Mar 8 '17 at 14:01
  • Not sure if there's precedence exist. But I've seen this problem before, when I started out with Lightning component in the beginning. – Praveen Mar 8 '17 at 17:31
  • @Praveen I tried what you suggested still not working – ozil Mar 9 '17 at 6:25
  • There is only one issue just remove the name attribute from <aura:handler ... /> and It will work as expected as shred by @Praveen – itzmukeshy7 Mar 14 '18 at 8:25
0

Try using this: $A.get("e.c:CreatChartEvent");

| improve this answer | |
  • You can also add description how this code help to resolve the issue. – Reshma Mar 8 '17 at 9:54
  • I have tried see in question – ozil Mar 8 '17 at 10:11
0

Your sample code uses: $A.get("event.c:CreatChartEvent")

and you say you also tried: component.getEvent("c:CreatChartEvent");

The right syntax is: $A.get("e.c:CreatChartEvent");

Unless you set up a namespace in which case you have to replace c: with yournamespace:

| improve this answer | |
0

@Christophe has the right answer to your question, so please select it and show him some love! You may want to reconsider the way you've modeled this though.

Instead of using a (relatively heavy) Application-level event, you can use Data Binding and Aura methods to avoid using events altogether (almost).

Change your App to include attributes for chartName and chartData. We'll reference these attributes in the ComponentB tag's parameters. By using the ! attribution symbol (instead of #), we're binding the value of each attribute between the two components: When the chartName value in ComponentB changes, the chartName attribute's value in the App is changed as well.

<aura:application>
    <aura:attribute name="chartName" type="String" default="BarChart"/>
    <aura:attribute name="chartData" type="String" default="BarChartData"/>

    <c:ComponentA />
    <c:ComponentB aura:id="compB" chartName="{!v.chartName}" chartData="{!v.chartData}" />

</aura:application>  

Note that I've changed <Component... to <c:Component.... (I have a feeling you just made a copy/paste error there.) I've also given ComponentB an aura:id to make it easier to reference later.

Instead of using an event handler in ComponentA, we'll define a method that will be called by the App. Calling the method will fire your createChart function.

<aura:method name="createMyChart" action="{!c.createChart}">
    <aura:attribute name="chartName"/>
    <aura:attribute name="chartData"/>
</aura:method>

As for handling the button click, you could use a (relatively light) Component event, which would bubble up to your App, telling the App to call ComponentB's createMyChart method, or you could go totally eventless (sort-of) by again using Data Binding, and an aura change handler. (The change handler fires the (built-in) valueChange.evt, so this isn't really "eventless", but you don't have to write your own lightning event. It's the little things...)

In your App, add an attribute that will be bound between the App and ComponentA. When the attribute changes, the change handler will fire a function that calls the App's callCreateChart function.

<aura:application>
    <aura:attribute name="chartName" type="String" default="BarChart"/>
    <aura:attribute name="chartData" type="String" default="BarChartData"/>

    <aura:attribute name="wasButtonClicked" type="Boolean" default="False"/>
    <aura:handler name="change" value="{!v.wasButtonClicked}" action="{!c.callCreateChart}"/>


    <c:ComponentA buttonClicked="{!v.wasButtonClicked}/>
    <c:ComponentB aura:id="compB" chartName="{!v.chartName}" chartData="{!v.chartData}" />

</aura:application> 

In ComponentA, add an attribute to store the bound Boolean value.

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

When the button in ComponentA is clicked, run the handleClick function in ComponentA's controller, which changes the value of the buttonClicked attribute to True.

handleClick : function(cmp, event){
    cmp.set("v.buttonClicked", "True");

}

Since the buttonClicked attribute's value is bound to the wasButtonClicked value in the App, the wasButtonClicked value will change to True. The change handler in the App will fire, calling the App's callCreateChart function.

In the App's controller:

callCreateChart : function(cmp, event){
    let isButtonClicked = event.getParam("value");

    if(isButtonClicked){
        let chName = cmp.get("v.chartName");
        let chData = cmp.get("v.chartData");

        // call the createChart method in ComponentB
        let compB = cmp.find("compB");
        compB.createMyChart(chName, chData);

        // set the wasButtonClicked value back to False
        cmp.set("v.wasButtonClicked", "False");
    }
}

Value binding changes the buttonClicked attribute in ComponentA back to False so it's ready for next time.

In ComponentB, the createMyChart method runs, firing your createChart function. You can get the parameters that were passed to the method like this:

createChart : function(cmp, event){
    let params = event.getParam("arguments");
    if(params){
        let chName = params.chartName;
        let chData = params.chartData;
    }

    alert("ComponentB creatChart :: chartName: " + chName + " :: chartData: " + chData);

}

...and you're all set. Sibling component communication without all the heavy events!

| improve this answer | |
0

Replace Component B handler with

    buttonClick: function(component, event, helper) {
    debugger // on button click it hits this debugger

    var selectedChart = "BarChart";
    var creatChartEvent = $A.get("e.c:CreatChartEvent");
    creatChartEvent.setParams({ "chartName": selectedChart, "chartDataProviderName" :  selectedChart+"Data"});
    creatChartEvent.fire();  

In line defyning, var creatChartEvent = $A.get("e.c:CreatChartEvent"); event should be replaced with e.

}  
| improve this answer | |
-1
One more issue is in your componentB controller file - 
In event attributes name are "chartName" and "chartData". But when using 
setParams method, you are using "chartName" that is right but 
"chartDataProviderName" is wrong because this attribute doesn't exist in event 
file. So change this variable to "chartData". 
| improve this answer | |

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.