You need to sign in to do that
Don't have an account?
Lighting aura:event not firing, or handler not executing
Hi there.
In my lightning app I have a few components:
I put console.debug's, alerts and component.set("v.testmessage", "fired") 's in the handlers but they never execute.
I then put one of the handlers as the init-handler and then it did execute the handler (with an undefined ID since the event hadn't yet been fired, which is reasonable).
I have triple-checked the event name, event type and handler action, everything matches. I have no compilation problems, I have no errors when I am using my app.
I also have no response whatsoever from my event. Any ideas?
**Registering component**
**Registering controller**
**List-child component**
**List-child controller.js**
In my lightning app I have a few components:
- one component has a ui:inputSelect and registers an event. the ui:inputSelect has a change attribute that fires a function, wherein the selected text (an ID) is put in an event and fired.
- one component that handles the event, is an aura:iteration list of a component that, on handling the event, should retrieve a list of items where a master-child lookup is the sent ID of the master object. This then displays all those child objects.
- the other component that handles the event, has three inputText fields, that are supposed to display the other fields of the master object
I put console.debug's, alerts and component.set("v.testmessage", "fired") 's in the handlers but they never execute.
I then put one of the handlers as the init-handler and then it did execute the handler (with an undefined ID since the event hadn't yet been fired, which is reasonable).
I have triple-checked the event name, event type and handler action, everything matches. I have no compilation problems, I have no errors when I am using my app.
I also have no response whatsoever from my event. Any ideas?
**Registering component**
<aura:component controller="PrefixMasterHeaderSelectorController"> <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> <aura:registerEvent name="updateMaster" type="c:PrefixMasterEvent" /> <aura:attribute name="masters" type="PrefixMaster__c[]"/> <label class="slds-master-element__label" for="masterSelector">Select a master to work with:</label> <div class="slds-master-element__control"> <div class="slds-select_container"> <ui:inputSelect aura:id="masterID" class="slds-select" change="{!c.masterHasChanged}"> <aura:iteration items="{!v.masters}" var="master"> <ui:inputSelectOption text="{!master.Id}" label="{!master.Name}" /> <!-- + ' (Last modified: ' + master.LastModifiedDate + ' by ' + master.LastModifiedBy.Name + ')'}"/> --> </aura:iteration> <ui:inputSelectOption text="newMaster" label="Create a new master" /> </ui:inputSelect> </div> </div> <c:PrefixMasterHeaderMaster /> </aura:component>
**Registering controller**
({ doInit : function(component, event, helper) { // Create the action var action = component.get("c.getMasters"); // Add callback behavior for when response is received action.setCallback(this, function(response) { var state = response.getState(); if (component.isValid() && state === "SUCCESS") { component.set("v.masters", response.getReturnValue()); } else { console.log("Failed with state: " + state); } }); // Send action off to be executed $A.enqueueAction(action); }, masterHasChanged : function(component, event, helper) { var masterID = component.find("masterID").get("v.value"); var masterEvent = component.getEvent("updateMaster"); masterEvent.setParams({"master" : masterID}) masterEvent.fire(); console.debug('UPDATE MASTER = ' + masterID); alert('Hiya! masterEvent ' + masterEvent.getParam("master")); } })
**List-child component**
<aura:component controller="PrefixListChildsController"> <aura:handler name="updateForm" event="c:PrefixFormEvent" action="{!c.loadChilds}" /> <aura:attribute name="childs" type="PrefixChild__c[]"/> <!-- <aura:handler name="saveChild" event="c:PrefixChildEvent" action="{!c.handleAddItem}"/> --> <!-- to reload the masters after adding a new child --> <div> <header class="slds-p-top--small"> <h3 class="slds-text-heading--small">Childs</h3> </header> <div id="list" class="row"> <aura:iteration items="{!v.childs}" var="child"> <aura:if isTrue="{!child.Order__c % 2 == 1}"> <div class="slds-p-around--small" style="background-color: lightblue; border-radius: 10px"> <c:PrefixChild child="{!child}"/> </div> <aura:set attribute="else" > <div class="slds-p-around--small" style="background-color: none; border-radius: 10px"> <c:PrefixChild child="{!child}"/> </div> </aura:set> </aura:if> </aura:iteration> {!v.testEventmessage} <c:PrefixNewChild /> </div> </div> </aura:component>
**List-child controller.js**
({ loadChilds : function(component, event, helper) { var action = component.get("c.getChilds"); var masterID = event.getParam("master"); action.setParams({ "masterID" : masterID }); console.debug('master id = ' + masterID); alert('load childs ' + masterID); component.set("v.testEventmessage", masterID); // Add callback behavior for when response is received action.setCallback(this, function(response) { var state = response.getState(); if (component.isValid() && state === "SUCCESS") { component.set("v.childs", response.getReturnValue()); } else { console.log("Failed with state: " + state); } }); // Send action off to be executed $A.enqueueAction(action); } })
After I found out that the firing component was able to handle the (component) event, but a component somewhere else (not a parent or child component, but, say, an uncle-component) was not, I changed the type of the event to application. Still didn't work, so I looked up the documentation and saw that an application-type event is registered slightly different.
**APPLICATION-TYPE EVENT:** **REGISTERING COMPONENT**
**FIRING CONTROLLER** (Note: instead of component.getEvent("eventName") you now use $A.get("e.c:EventName") !
I'm not sure what the 'e' stands for, but I'm pretty sure the 'c' part is the namespace, and be careful to put the name of the event FILE as 'EventName' in the $A.get() parameter.)
**HANDLING COMPONENT** (Note: the main difference is: with an application event there is no need (or use) for an event 'name', and I'm not sure why it has to be specified at the registerEvent tag other than it's a required attribute of the tag.)
**HANDLING CONTROLLER**
All Answers
After I found out that the firing component was able to handle the (component) event, but a component somewhere else (not a parent or child component, but, say, an uncle-component) was not, I changed the type of the event to application. Still didn't work, so I looked up the documentation and saw that an application-type event is registered slightly different.
**APPLICATION-TYPE EVENT:** **REGISTERING COMPONENT**
**FIRING CONTROLLER** (Note: instead of component.getEvent("eventName") you now use $A.get("e.c:EventName") !
I'm not sure what the 'e' stands for, but I'm pretty sure the 'c' part is the namespace, and be careful to put the name of the event FILE as 'EventName' in the $A.get() parameter.)
**HANDLING COMPONENT** (Note: the main difference is: with an application event there is no need (or use) for an event 'name', and I'm not sure why it has to be specified at the registerEvent tag other than it's a required attribute of the tag.)
**HANDLING CONTROLLER**
As for the 'name' attribute in aura:registerEvent, you're correct. The attribute must be specified, though it is only used for COMPONENT and is ignored for APPLICATION.
I have 2 components and linking them with a lightning Component event.
but it seems that the event is not getting handeled as i am not able to see log and alert from child component's handleSubmit method. following is the code:
Please suggest.
Parent Component :
<aura:component controller="getContactList" implements="force:appHostable,force:hasRecordId,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<aura:attribute name="cont" type="String"/>
<aura:attribute name="ContactList" type="Contact[]"/>
{!v.recordId} <br/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:handler name="CreateChild" event="c:childContEvt" action="{!c.handleCompEvt}"/>
<aura:iteration items="{!v.ContactList}" var="con">
<lightning:card footer="{!con.Phone}" title="Phone">
<aura:set attribute="actions">
<lightning:button name="{!con.Id}" label="Details" onclick="{!c.contDetail}"/>
</aura:set>
<p class="slds-p-horizontal_small">
{!con.Email} <br/>
</p>
</lightning:card>
</aura:iteration>
</aura:component>
Parent Component client side controller :
({
doInit : function(component, event, helper) {
var action = component.get("c.getContList");
//console.log('AccountId', component.get("v.recordId"));
var accId = component.get("v.recordId");
action.setParams({
AccountId: accId,
});
action.setCallback(this, function(response){
var returnValue = response.getReturnValue();
//console.log('returnValue', returnValue);
component.set("v.ContactList", returnValue);
});
$A.enqueueAction(action, false);
},
contDetail : function(component, event, helper) {
var evtSrc = event.getSource();
var conId = evtSrc.get('v.name');
var detailevt = $A.get("e.force:navigateToSObject");
detailevt.setParams({
recordId : conId
});
detailevt.fire();
},
handleCompEvt : function(component, event, helper) {
var evt = event.getSource();
Console.log(event.getName());
alert('test');
}
})
Component Event :
<aura:event type="COMPONENT" description="Event template" >
<aura:attribute name="cont" type="String"/>
</aura:event>
Child Component :
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<aura:attribute name="disabled" type="Boolean" default="false" />
<aura:attribute name="saved" type="Boolean" default="false" />
<aura:attribute name="showSpinner" type="Boolean" default="true" />
<aura:attribute name="recordId" type="String" />
<aura:registerEvent name="CreateChild" type="c:childContEvt"/>
<aura:attribute name="createCont" type="Contact" default="{sobjectName:'Contact',
Name:'',
Email:'',
Phone:''}"/>
<aura:attribute name="accountId" type="String"/>
<lightning:recordEditForm
onload="{!c.handleLoad}"
onsubmit="{!c.handleSubmit}"
onsuccess="{!c.handleSuccess}"
objectApiName="Contact">
<!-- the messages component is for error messages -->
<lightning:inputField fieldName="Name" value="{!v.createCont.Name}"/>
<lightning:inputField fieldName="Email" value="{!v.createCont.Email}"/>
<lightning:inputField fieldName="Phone" value="{!v.createCont.Phone}"/>
<div class="slds-m-top_medium">
<lightning:button disabled="{!v.disabled}" variant="brand" type="submit" name="save" label="Save" />
</div>
</lightning:recordEditForm>
</aura:component>
Child component client side Controller :
({
handleLoad: function(cmp, event, helper) {
cmp.set('v.showSpinner', false);
},
handleSubmit: function(cmp, event, helper) {
cmp.set('v.disabled', true);
cmp.set('v.showSpinner', true);
var compEvent = cmp.getEvent('CreateChild');
console.log(compEvent.getName());
compEvent.setParams({
cont :cmp.get('v.recordId'),
});
compEvent.fire();
console.log('NewCont Id', cmp.get('v.recordId'));
},
handleError: function(cmp, event, helper) {
// errors are handled by lightning:inputField and lightning:messages
// so this just hides the spinner
cmp.set('v.showSpinner', false);
},
handleSuccess: function(cmp, event, helper) {
var params = event.getParams();
cmp.set('v.recordId', params.response.id);
cmp.set('v.showSpinner', false);
cmp.set('v.disabled', false);
},
})