5

change handler doesn't work when the attribute is a list which can be updated an aura:iteration.

In the following example, we never go to controller method itemsChange ( except at the init) whereas the attribute value is well updated, as you can see in the console when you click on "click me".

Related doc: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ref_aura_valueChange.htm

Snippet to reproduce with 2 copy/paste :

App :

    <aura:attribute name="SomeList" type="Object[]" />

    <aura:handler name="change" value="{!v.SomeList}" action="    {!c.itemsChange}"/>

    <aura:iteration items="{!v.SomeList}" var="ListItem">
        <c:CmpInputText value="{!ListItem.SomeVal}" />
    </aura:iteration>

    <a onclick="{!c.clickMe}">CLICK ME</a>

</aura:application>

Controller:

({
    doInit : function(component, event, helper) {
        var SomeList = [
            {'SomeVal': 'INITIAL'},
            {'SomeVal': 'VALUES'},
            {'SomeVal': 'HERE'}
        ] ;
        component.set('v.SomeList',SomeList);
        console.debug('INIT VALUES' +     JSON.stringify(component.get('v.SomeList')));
    },

    clickMe : function(component, event, helper) {
        console.debug('AFTER CLICK     '+JSON.stringify(component.get('v.SomeList')));
    } ,

    itemsChange : function(component, event, helper) {
        alert('SomeList has changed');
        console.debug('ONCHANGE :'+     JSON.stringify(component.get('v.SomeList'),null,2));
    }        
})
8
  • Did you try to write <aura:handler name="change" value="{!v.ListItem.SomeVal}" action=" {!c.itemsChange}"/> inside of aura:iteration?
    – Patlatus
    Oct 27, 2016 at 12:36
  • I guess it should work. In the meantime you can still add a change handler directly on your c:CmpInputText component. I don't know what's inside your component, but for a standard component it would look like this: <ui:inputText value="{!ListItem.SomeVal}" change="{!c.itemsChange}"/> Oct 27, 2016 at 12:38
  • @Patlatus Can not save with aura:handler inside aura:iteration FabienTaillon > it contains an input type="text" . I can have lots of input components inside this aura:iteration, I would really prefer the aura:handler change to work as described in the documentation Oct 27, 2016 at 12:42
  • 1
    @NicolasVuillamy if putting aura:handler inside aura:iteration doesn't work for you then you can create your own event and fire it inside of c:CmpInputText and implement handler for your custom event in your application.
    – Patlatus
    Oct 27, 2016 at 12:57
  • @NicolasVuillamy itemsChange method will be called when you do component.set('v.SomeList',SomeList); in the doInit. I checked it in my org, it works as expected.
    – Praveen
    Oct 27, 2016 at 15:28

1 Answer 1

1

I was facing a similar issue and I found a workaround for this.

Parent component

<aura:component>
   <aura:attribute name="lstAddresses" type="Address__c[]" access="global"/>
   <aura:handler name="change" value="{!v.lstAddresses}" action="{!c.itemsChange}"/>
   <aura:if isTrue="{!v.showAddAddress}">
         <c:AddEditAddress myObject="{'sobjectType': 'Address__c'}" lstAddresses="{!v.lstAddresses}"  />
      </aura:if>
</aura:component>

Child component

<aura:component>
   <aura:attribute name="lstAddresses" type="Address__c[]" access="global"/>
</aura:component>

Here I have just cut short the code, which is sufficient enough to clear the doubt So Here in the controller js of child component I was adding a address object in the list aura attribute, but the handler for lstAddresses change event was not firing, inshort some how the bidirectional binding was not working as expected

I just updated my code section little bit where I was performing push on the list like this

var lstAddresses = JSON.parse(JSON.stringify(component.get("v.lstAddresses")));
lstAddresses.push(addressObj);
component.set("v.lstAddresses",lstAddresses);

I found that now the change event handler of parent component gets called in init as well as on pushing a new address record from child component. So may be it is the case that in case of collection we have to use this way. Let me know if that worked for you

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .