1

Array is not updating when the reference which was passed as an argument to the component (in which update does not happen) is updated.

Let me provide the code first.

campingApp.app :

<aura:application extends="force:slds">
    <c:camping />
</aura:application>

camping.cmp :

<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]" default="[]"/>
    <aura:attribute name="item" type="Camping_Item__c" default="{ 
                        'sobjectType': 'Camping_Item__c',
                        'campingItemName': 'campingItemNameDefault',
                        'Price__c': 0,
                        'Quantity__c': '0',
                        'Packed__c': false }"/>
    <c:campingHeader />
    <c:campingItemForm item="{!v.item}" items="{!v.items}" />
    <c:campingList items="{!v.items}"/>
</aura:component>

campingHeader.cmp :

<aura:component >
<lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="action:goal"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping list</h1>
            </div>
        </lightning:layoutItem>
    </lightning:layout>

</aura:component>

campingItemForm.cmp :

<aura:component >
    <aura:attribute name="item" type="Camping_Item__c" required="true"/>
    <aura:attribute name="items" type="Camping_Item__c[]" required="true"/>
    <form class="slds-form--stacked">          
            <lightning:input aura:id="campingItemForm" label="Name"
                             name="campingItemName"
                             value="{!v.item.Name}"
                             required="true"/> 
            <lightning:input aura:id="campingItemForm" label="Quantity"
                             name="campingItemQuantity"
                             value="{!v.item.Quantity__c}"
                             min="1"/>
            <lightning:input aura:id="campingItemForm" type="number" label="Price"
                             name="campingItemPrice"
                             formatter="currency"
                             step="0.01"
                             value="{!v.item.Price__c}"/>
            <lightning:input aura:id="campingItemForm" type="checkbox" label="Packed"  
                             name="campingItemIsPacked"
                             checked="{!v.item.Packed__c}"/>
            <lightning:button label="Create Camping Item" 
                              class="slds-m-top--medium"
                              variant="brand"
                              onclick="{!c.clickCreateItem}"/>
        </form>
</aura:component>

campingItemFormController.js :

({
    clickCreateItem : function(component, event, helper) {
        var newItem = component.get("v.item");
        var items = component.get("v.items");
        items.push(newItem);
        newItem = {sobjectType: "Camping_Item__c"};;
        component.set("v.item", newItem);
        component.set("v.items", items);
    }
})

campingList.cmp :

<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]" />
    <aura:iteration items="{!items}" var="item">
        <c:campingListItem item="{!item}" />
    </aura:iteration>
</aura:component>

Once more the problem explanation (more detailed this time). I fill out the campingItemForm, then I click the button to add the campinItem which will consist of the values in the campingItemForm. I am expecting these lines to update all the usages of the item and items attributes of the camping.cmp:

component.set("v.item", newItem);
component.set("v.items", items);

And hence after the update I expect the value of the attribute items of the child component campingItemsList.cmp of the camping.cmp component to be updated. But it does not update. I mean after submitting the form by clicking button the part where the list of items is to be displayed remains empty.

Using the expression console.log(JSON.stringify(items); before the line items.push(newItem); and after the line two times (I tried to create item list component twice) I noticed that the values in the array really persist. So, the problem is definitely in the update.

Now it seems that the reason is that only those components are updated to which the reference relates directly. And since in the case the reference gets in the campingList.cmp indirectly (as a parameter) it won`t be updated. Is it the case? If so, are there are any ways around it?

Here it is said:

Pass in a reference to the attribute to the child component.

<c:childComponent myValue="{!v.B}"/>

When the childComponent updates myValue, v.B will also update.

So, I may assume that the problem here is not parent-child attribute renewal related.

If it is not the case, then what am I doing wrong here?

2

The stupidity of my question is unforgivable, but in case someone will get the same problem here is the root of the problem.

As shown in the documentation, one should always specify the v. in the iteration attribute.

So to work correctly the campingList.cmp should look like this:

<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]" />
    <aura:iteration items="{!v.items}" var="item">
        <c:campingListItem item="{!item}" />
    </aura:iteration>
</aura:component>
  • I'd give yourself a break here. Needing v. in most cases but not all is a pretty painful design choice by the designers. – Keith C May 22 '18 at 11:54

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.