function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Peter McGavinPeter McGavin 

The campingList component isn't iterating the array of 'items' and creating 'campingListItem' components.

Hi,

I have managed to get the challenge working but the trailhaed keeps displaying the following message when I press the Check challgene button:
The campingList component isn't iterating the array of 'items' and creating 'campingListItem' components.

It could possibly be the way I have written the code (as separate components) compared to what the trailhead is expecting:

Here is my code:

a) harnessApp.app

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

</aura:application>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

b) campingHeader.cmp

<aura:component >
    <!--<h1>Camping List</h1>-->
<!-- PAGE HEADER -->
    <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="action:goal" alternativeText="Camping List"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping Item</h1>
                <h2 class="slds-text-heading--medium">My Camping Items</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
    <!-- / PAGE HEADER -->
    
</aura:component>

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
c) campingList.cmp

<aura:component >
    
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    
    <aura:attribute name="newItem" type="Camping_Item__c"
     default="{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Packed__c': '',
                    'Price__c': '0',
                    'Quantity__c': '0' }"/>
    
    <!-- NEW CAMPING ITEM FORM -->
    <lightning:layout >
        <lightning:layoutItem padding="around-small" size="6">

        <!-- CREATE NEW CAMPING ITEM -->
    <div aria-labelledby="newcampingitemform">

    <!-- BOXED AREA -->
    <fieldset class="slds-box slds-theme--default slds-container--small">

    <legend id="newcampingitemform" class="slds-text-heading--small 
      slds-p-vertical--medium">
      Add Camping Item
    </legend>

    <!-- CREATE NEW CAMPING ITEM FORM -->
    <form class="slds-form--stacked">  
       
        <lightning:input aura:id="campingitemform" label="Item Name"
                         name="campingitemname"
                         value="{!v.newItem.Name}"
                         required="true"/> 
        
        <lightning:input type="number" aura:id="campingitemform" label="Quantity"
                         name="campingitemquantity"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter at least 1"/>
        
        <lightning:input type="number" aura:id="campingitemform" label="Price"
                         name="campingitemprice"
                         formatter="currency"
                         step="0.01"
                         value="{!v.newItem.Price__c}" />
        
        <lightning:input type="checkbox" aura:id="campingitemform" label="Packed?"  
                         name="campingitempacked"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Item" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
    </form>
    <!-- / CREATE NEW CAMPING ITEM FORM -->

  </fieldset>
  <!-- / BOXED AREA -->

</div>
<!-- / CREATE CAMPING NEW ITEM -->

        </lightning:layoutItem>
    </lightning:layout>
    <!-- / NEW CAMPING ITEM FORM -->
   
    <c:campingListItem items="{!v.items}"/>

  
</aura:component>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

d) campingListController.js

({
    clickCreateItem: function(component, event, helper) {
        var validItem = component.find('campingitemform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        // If we pass error checking, do some real work
        if(validItem){
            // Create the new expense
            var newItem = component.get("v.newItem");
            console.log("Create item: " + JSON.stringify(newItem));
            helper.createItem(component, newItem);
        }
   
    }
 
})
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

e) campingListHelper.js

({createItem: function(component, item) {
        var theItem = component.get("v.items");
 
        // Copy the expense to a new object
        // THIS IS A DISGUSTING, TEMPORARY HACK
        var newItem = JSON.parse(JSON.stringify(item));
 
        console.log("Item before 'create': " + JSON.stringify(theItem));
        theItem.push(newItem);
        component.set("v.items", theItem);
        console.log("Item after 'create': " + JSON.stringify(theItem));
        component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false });
        }
 })
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

f) campingListItem.cmp

<aura:component >

    <aura:attribute name="items" type="Camping_Item__c[]"/>

    <lightning:card title="Items">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="item">
                <c:campingListItems item="{!item}"/>
            </aura:iteration>
        </p>
    </lightning:card>
    
</aura:component>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

g) campingListItems.cmp

<aura:component >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <!--aura:attribute name="formatdate" type="Date"/-->
    <aura:attribute name="item" type="Camping_Item__c"/>


    <lightning:card title="{!v.item.Name}" iconName="standard:scan_card"
                    class="{!v.item.Packed__c ?
                           'slds-theme--success' : ''}">
        <aura:set attribute="footer">
            <!--p>Date: <lightning:formattedDateTime value="{!v.formatdate}"/></p-->
            <!--p class="slds-text-title"><lightning:relativeDateTime value="{!v.formatdate}"/></p-->
        </aura:set>
        
        <p class="slds-p-horizontal--small">
            Quantity: {!v.item.Quantity__c}
        </p>
        
        <p class="slds-text-heading--medium slds-p-horizontal--small">
           Price: <lightning:formattedNumber value="{!v.item.Price__c}" style="currency"/>
        </p>

        <p>
            <lightning:input type="toggle" 
                             label="Packed?"
                             name="packed"
                             class="slds-p-around--small"
                             checked="{!v.item.Packed__c}"
                             messageToggleActive="Yes"
                             messageToggleInactive="No"
                             onchange="{!c.clickPacked}"/>
        </p>
    </lightning:card>
</aura:component>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Thanks in advance for your assistance on this. 


 
Best Answer chosen by Peter McGavin
Peter McGavinPeter McGavin
Resolved it myself. 

All Answers

Peter McGavinPeter McGavin
Hi Guys,

just wondering if there was anyone who could assist with my query? Thanks.
Peter
Peter McGavinPeter McGavin
Resolved it myself. 
This was selected as the best answer
Augustin Rieunier 5Augustin Rieunier 5
Hi Peter,
Can you explain how you solved that ?
I'm stuck here as well.
It complains with the exact same message than you, except that I have the iteration properly configured. It's working just find when testing it ..

Here's my campingList component :
<aura:component >
     <!-- Attributes -->
    <aura:attribute name="newItem" type="Camping_Item__c"
         default="{ 'sobjectType': 'Camping_Item__c',
                        'Name': '',
                        'Packed__c': false,
                        'Price__c': 0,
                        'Quantity__c': 0}"/>

    <aura:attribute name="items" type="Camping_Item__c[]"/>
    
    <!-- NEW Camping Item FORM -->
    <lightning:layout >
        <lightning:layoutItem padding="around-small" size="6">

            <!-- CREATE NEW ITEM -->
            <div aria-labelledby="campingform">
    
                <!-- BOXED AREA -->
                <fieldset class="slds-box slds-theme--default slds-container--small">
        
                <legend id="campingform" class="slds-text-heading--small 
                  slds-p-vertical--medium">
                  Add Camping Item
                </legend>
          
                <!-- CREATE NEW EXPENSE FORM -->
                <form class="slds-form--stacked">          
                    <lightning:input aura:id="campingform" label="Camping Item Name"
                                     name="campingname"
                                     value="{!v.newItem.Name}"
                                     required="true"/> 
                    <lightning:input type="currency" aura:id="campingform" label="Price"
                                     name="campingprice"
                                     min="0.1"
                                     step="0.01"
                                     value="{!v.newItem.Price__c}"
                                     messageWhenRangeUnderflow="Enter an amount that's at least 0.10."/>
                    <lightning:input type="number" aura:id="campingform" label="Quantity"
                                     name="campingquantity"
                                     min="1"
                                     value="{!v.newItem.Quantity__c}"
                                     messageWhenRangeUnderflow="Enter an amount that's at least 1."/>
                    <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                                     name="campingpacked"
                                     checked="{!v.newItem.Packed__c}"/>
                    <lightning:button label="Create Camping Item" 
                                      class="slds-m-top--medium"
                                      variant="brand"
                                      onclick="{!c.clickCreateItem }"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
          
              </fieldset>
              <!-- / BOXED AREA -->
        
            </div>
            <!-- / CREATE NEW EXPENSE -->

        </lightning:layoutItem> 
    </lightning:layout>
        
    <!-- Affichage des camping items-->
    <lightning:card title="Camping Items">
        <p class="slds-p-horizontal--small">
            <aura:iteration var="campingListItem" items="{!v.items}" >
                <c:campingListItem item="{!campingListItem}"/>
            </aura:iteration>
        </p>
    </lightning:card>   
</aura:component>
And what it displays

Look & Feel

Hope you'll have some guidance 

Cheers
 
Augustin Rieunier 5Augustin Rieunier 5
Well, found a solution after looking at some blogs
Problem was on the iteration part at the bottom, althought it's more related to the tags around than the iteration itself
With that piece of code it worked:
 
<div class="slds-card slds-p-top--medium">
        <header class="slds-card__header">
            <h3 class="slds-text-heading--small">Items</h3>
        </header>
         
        <section class="slds-card__body">
            <div id="list" class="row">
                <aura:iteration items="{!v.items}" var="items">
                    <c:campingListItem item="{!items}"/>
                </aura:iteration>
            </div>
        </section>
    </div>

 
Sumanta Mukherjee 14Sumanta Mukherjee 14
Hi, 
While working on the trailhead challenge "Connect Components with Events" I am getting this error - "The campingList component isn't iterating the array of items and creating campingListItem components."
Here is my code.

Thanks.

campingItem.app
<aura:application extends="force:slds">
    <c:campingHeader/>	
</aura:application>

campingHeader.cmp
<aura:component>
    <!-- PAGE HEADER -->
    <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem>
            <lightning:icon iconName="action:goal" alternativeText="Camping Items"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping Items</h1>
                <h2 class="slds-text-heading--medium">New Camping Items</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
    <!-- / PAGE HEADER -->
    <!-- NEW EXPENSE FORM -->
    <lightning:layout>
        <lightning:layoutItem padding="around-small" size="6">
        <!-- [[ expense form goes here ]] -->
            <c:campingList/>
        </lightning:layoutItem>
    </lightning:layout>
    <!-- / NEW EXPENSE FORM -->
</aura:component>

campingList.cmp
<aura:component controller="CampingListController">
    <aura:attribute name="items" type="Camping_Item__c[]"/>
 
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <aura:handler name="addItem" event="c:addItemEvent" action="{!c.handleAddItem}"/>
	
    <!--Call campingListForm component for new Item Entry Form-->
    <c:campingListForm/>
	
    <!-- /Creating a list of items -->
    <lightning:card title="Items">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="campingItem">
                <c:campingListItem campingItem="{!campingItem}"/>
            </aura:iteration>
        </p>
    </lightning:card>
	
</aura:component>

campingListController.js
({
  
    // Load camping items from Salesforce
    doInit: function(component, event, helper) {
        // Create the action
        var action = component.get("c.getItems");
        // Add callback behavior for when response is received
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.items", response.getReturnValue());
            }
            else {
                console.log("Failed with state: " + state);
            }
        });
        // Send action off to be executed
        $A.enqueueAction(action);
    },
    
    handleAddItem: function(component, event, helper) {
        
        component.set("v.newItem",
                     { 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Packed__c': false,
                    'Price__c': 0,
                    'Quantity__c': 0});
    }
})
campingListItem.cmp
<aura:component>
    <aura:attribute name="campingItem" type="Camping_Item__c"/>
    <lightning:card title="{!v.campingItem.Name}" iconName="action:goal"
                    class="{!v.campingItem.Packed__c ?
                           'slds-theme--success' : ''}">
        <p class="slds-text-heading--medium slds-p-horizontal--small">
           Price: <lightning:formattedNumber value="{!v.campingItem.Price__c}" style="currency"/>
        </p>
        <p class="slds-text-heading--medium slds-p-horizontal--small">
           Quantity: <lightning:formattedNumber value="{!v.campingItem.Quantity__c}" style="decimal"/>
        </p>
        <p>
            <lightning:input type="toggle" 
                             label="Packed?"
                             name="packed"
                             class="slds-p-around--small"
                             checked="{!v.campingItem.Packed__c}"
                             messageToggleActive="Yes"
                             messageToggleInactive="No"
                             onchange="{!c.clickPacked}"/>
        </p>
    </lightning:card>
</aura:component>

campingListForm.cmp
<aura:component controller="CampingListController">
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c"
         default="{ 'sobjectType': 'Camping_Item__c',
                        'Name': '',
                        'Quantity__c': 0,
                        'Price__c': 0,
                        'Packed__c': false }"/>
   
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>

    <aura:registerEvent name="addItem" type="c:addItemEvent"/>

    <!-- CREATE NEW CAMPING ITEM -->
    <div aria-labelledby="newitemform">
        <!-- BOXED AREA -->
        <fieldset class="slds-box slds-theme--default slds-container--small">
        <legend id="newitemform" class="slds-text-heading--small 
          slds-p-vertical--medium">
          Add New Camping Item
        </legend>
  
        <!-- CREATE NEW CAMPING ITEM FORM -->
        <form class="slds-form--stacked">          
            <lightning:input aura:id="newitemform" label="Camping Item Name"
                             name="itemname"
                             value="{!v.newItem.Name}"
                             required="true"/> 
            <lightning:input type="number" aura:id="newitemform" label="Price"
                             name="itemprice"
                             min="0.1"
                             formatter="currency"
                             step="0.01"
                             value="{!v.newItem.Price__c}"
                             messageWhenRangeUnderflow="Enter a price that's at least $0.10."/>
            <lightning:input type="number" aura:id="newitemform" label="Quantity"
                             name="itemquantity"
                             min="1"
                             step="1"
                             value="{!v.newItem.Quantity__c}" 
                             messageWhenRangeUnderflow="Enter a quantity that's greater than 0."/>
            <lightning:input type="checkbox" aura:id="newitemform" label="Packed?"  
                             name="itempacked"
                             checked="{!v.newItem.Packed__c}"/>
            <lightning:button label="Create New Item" 
                              class="slds-m-top--medium"
                              variant="brand"
                              onclick="{!c.submitForm}"/>
        </form>
        <!-- / CREATE NEW CAMPING ITEM FORM -->
  
      </fieldset>
      <!-- / BOXED AREA -->
    </div>
    <!-- / CREATE NEW CAMPING ITEM -->
</aura:component>

campingListFormController.js
({
    //Create new camping item
	submitForm : function(component, event, helper) {
        
        var isFormValid = component.find("newitemform").reduce(function(validSoFar, inputCmp){
            // Displays error messages for invalid fields
        	inputCmp.showHelpMessageIfInvalid();    	
            return validSoFar && inputCmp.get("v.validity").valid;
        });
        
        if (isFormValid) {
            
            var newCampingItem = component.get("v.newItem");
            helper.createItem(component, newCampingItem);
           
        }
	}
})

campingListFormHelper.js
({
     createItem : function(component) {
                       
        var action = component.get("c.saveItem");
        action.setParams({
            "item": item
        });
        
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {        
                var items = component.get("v.items");
                items.push(item);
                component.set("v.items",items);
            }
        });
        $A.enqueueAction(action);
         
        var item = event.getParam("item");
        var newItem = component.get("v.newItem");
        var addEvent = component.getEvent("addItem");
        addEvent.setParams({"item" : newItem});
        addEvent.fire();
        /*component.set("v.newItem",
                     { 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Packed__c': false,
                    'Price__c': 0,
                    'Quantity__c': 0});*/
    }
    
    
})

campingListController.apxc
public with sharing class CampingListController {
    @AuraEnabled
    public static List<Camping_Item__c> getItems() {
		List<Camping_Item__c> campingItems = [SELECT Id,Name,Price__c,Packed__c,Quantity__c FROM Camping_Item__c];
        return campingItems;
    }
    
    @AuraEnabled
    public static Camping_Item__c saveItem(Camping_Item__c campingItem) {
        upsert campingItem;
        return campingItem;
    }
}

addItemEv​​​​​​​ent.evt​​​​​​​​​​​​​​​​​​​​​​​​​​​​
<aura:event type="COMPONENT">
    <aura:attribute name="item" type="Camping_Item__c"/>
</aura:event>
Rakesh SRakesh S
Hi Peter,

i'm also getting same error but not able to replicate this error. Please find the following code and let me know the issue of the code.
CampingList.cmp:

<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>    
    <lightning:card title="Campings">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="newItem">
                <c:campingListItem newItem="{!newItem}"/>
                <!--Name: {!newItem.name}-->
            </aura:iteration>
        </p>
    </lightning:card>    
</aura:component>
 
CampingListItem.cmp:
<aura:component >    
    <aura:attribute name="newItem" type="Camping_Item__c"/>
    <ui:outputText value="{!v.newItem.Name}" />
    <!--<ui:outputCheckbox value="{!v.item.Packed__c}"/>-->
    <p>
        <lightning:input type="toggle"                            
                         label="Packed?"                           
                         name="packed"                         
                         checked="{!v.newItem.Packed__c}" id="packed" />
     </p>
    <p>Price:
        <lightning:formattedNumber value="{!v.newItem.Price__c}" style="currency"/>
    </p>
    <p>Quantity:
        <lightning:formattedNumber value="{!v.newItem.Quantity__c}"/>
    </p>
    <lightning:button label="Packed!" onclick="{!c.packItem}" />    
</aura:component>

appriciate your help.

Thanks,
Rakesh 
Shawn Sabbini 4Shawn Sabbini 4
Thank you Augustin Rieunier 5
As you said, it seems to be an issue of the surrounding tags somehow.
 
<!--  Iteration attempt 1, fails -->
    <!-- Resulting error : The campingList component isn't iterating the array of 'items' and creating 'campingListItem' components. -->
    <lightning:card title="Camping Items">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="item">
                <c.campingListItem item="{!item}" />
            </aura:iteration>
        </p>
    </lightning:card>
    <!-- end attempt 1 -->
<!-- Attempt 2 passes -->    
    <div class="slds-card slds-p-top--medium">
      <header class="slds-card__header">
          <h3 class="slds-text-heading--small">Items</h3>
      </header>
      <section class="slds-card__body">
          <div id="list" class="row">
              <aura:iteration items="{!v.items}" var="item">
                  <c:campingListItem item="{!item}"/>
              </aura:iteration>
          </div>
      </section>
  </div>    
 <!-- end Attempt 2 -->

It isn't logical to me that it should be this way.  If there is a good explanation would love to hear about it.
​​​​​​​

    
 
Syam SunderSyam Sunder
Hi Guys,

While working on the trailhead challenge "Connect Components with Events" I am getting this error - "The campingList component isn't iterating the array of items and creating campingListItem components."

I have complited the challenge with below code.

campingHeader.cmp
<aura:component >
    <!--<h1>Camping List</h1>-->
<!-- PAGE HEADER -->
    <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="action:goal" alternativeText="Camping List"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping Item</h1>
                <h2 class="slds-text-heading--medium">My Camping Items</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
    <!-- / PAGE HEADER -->    
</aura:component>
campingList.cmp
<aura:component >
  	<aura:attribute name="items" type="Camping_Item__c[]"/>    
    <aura:attribute name="newItem" type="Camping_Item__c"
     default="{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Packed__c': '',
                    'Price__c': '0',
                    'Quantity__c': '0' }"/>
    
    <!-- NEW CAMPING ITEM FORM -->
    <lightning:layout >
        <lightning:layoutItem padding="around-small" size="6">
            
        <!-- CREATE NEW CAMPING ITEM -->
    <div aria-labelledby="newcampingitemform">

    <!-- BOXED AREA -->
    <fieldset class="slds-box slds-theme--default slds-container--small"> 
        
    <legend id="newcampingitemform" class="slds-text-heading--small slds-p-vertical--medium">
      Add Camping Item
    </legend> 
        
    <!-- CREATE NEW CAMPING ITEM FORM -->
    <form class="slds-form--stacked">  
       
        <lightning:input aura:id="campingitemform" label="Camping Item Name"
                         name="campingitemname"
                         value="{!v.newItem.Name}"
                         required="true"/> 
        
        <lightning:input type="number" aura:id="campingitemform" label="Quantity"
                         name="campingitemquantity"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter at least 1"/>
        
        <lightning:input type="number" aura:id="campingitemform" label="Price"
                         name="campingitemprice"
                         formatter="currency"
                         step="0.01"
                         value="{!v.newItem.Price__c}" />
        
        <lightning:input type="checkbox" aura:id="campingitemform" label="Packed?"  
                         name="campingitempacked"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping Item" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
    </form>
    <!-- / CREATE NEW CAMPING ITEM FORM -->

  </fieldset>
  <!-- / BOXED AREA -->

</div>
<!-- / CREATE CAMPING NEW ITEM -->

   </lightning:layoutItem>
    </lightning:layout>
    <!-- / NEW CAMPING ITEM FORM -->  
    
    <lightning:card title="Camping List Items">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="itemm">
                <c:campingListItem item="{!itemm}"/>
            </aura:iteration>
        </p>
    </lightning:card>   
</aura:component>
campingListController.js
({
    clickCreateItem: function(component, event, helper) {
        var validItem = component.find('campingitemform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        // If we pass error checking, do some real work
        if(validItem){
            // Create the new expense
            var newItem = component.get("v.newItem");
            console.log("Create item: " + JSON.stringify(newItem));            
            var theItem = component.get("v.items");        
        	var newItemtoAdd = JSON.parse(JSON.stringify(newItem)); 
            console.log("Item before 'create': " + JSON.stringify(theItem));
            theItem.push(newItemtoAdd);
            component.set("v.items", theItem);
            console.log("Item after 'create': " + JSON.stringify(theItem));
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                        'Name': '',
                        'Quantity__c': 0,
                        'Price__c': 0,
                        'Packed__c': false });           
        }
   
    }
 
})
campingListItem.cmp
<aura:component >
    <!-- <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> -->
    <!--aura:attribute name="formatdate" type="Date"/-->
    <aura:attribute name="item" type="Camping_Item__c"/>

    <lightning:card title="{!v.item.Name}" iconName="action:goal"
                    class="{!v.item.Packed__c ?
                           'slds-theme--success' : ''}">               
        <p class="slds-p-horizontal--small">
            Quantity: {!v.item.Quantity__c}
        </p>        
        <p class="slds-text-heading--medium slds-p-horizontal--small">
           Price: <lightning:formattedNumber value="{!v.item.Price__c}" style="currency"/>
        </p>
        <p>
            <lightning:input type="toggle" 
                             label="Packed?"
                             name="packed"
                             class="slds-p-around--small"
                             checked="{!v.item.Packed__c}"
                             messageToggleActive="Yes"
                             messageToggleInactive="No"/>
        </p>
    </lightning:card>
</aura:component>

All the best.



 
JIAN DONGJIAN DONG
Hi Guys,
I passed the challenge with below code.
Good Luck!

1.campingListApp.app
<aura:application extends="force:slds">
    <c:campingList/>
</aura:application>

2.campingList.cmp
<aura:component>
     <aura:attribute name="items" type="Camping_Item__c[]"/>
     <aura:attribute name="newItem" type="Camping_Item__c"
         default="{ 'sobjectType': 'Camping_Item__c',
                        'Name': '',
                        'Quantity__c': 0,
                        'Price__c': 0,
                        'Packed__c': false }"/>
    <!-- PAGE HEADER -->
    <c:campingHeader/>
    <!-- / PAGE HEADER -->

    <lightning:layout>
        <lightning:layoutItem padding="around-small" size="6">
        <!-- CREATE NEW ITEM -->
        <div aria-labelledby="newitemform">
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
            <legend id="newitemform" class="slds-text-heading--small 
              slds-p-vertical--medium">
              Add Item
            </legend>
      
            <!-- CREATE NEW ITEM FORM -->
            <form class="slds-form--stacked">          
                <lightning:input aura:id="itemform" label="Item Name"
                                 name="itemname"
                                 value="{!v.newItem.Name}"
                                 required="true"
                                 messageWhenValueMissing="Did you forget me?"/> 
                <lightning:input type="number" aura:id="itemform" label="Quantity"
                                 name="itemquantity"
                                 min="1"
                                 value="{!v.newItem.Quantity__c}"
                                 messageWhenRangeUnderflow="Enter an quantity that's at least 1."/>
                <lightning:input type="number" aura:id="itemform" label="Price"
                                 name="itemprice"
                                 min="0.01"
                                 formatter="currency"
                                 step="0.001"
                                 value="{!v.newItem.Price__c}"
                                 messageWhenRangeUnderflow="Enter an price that's at least $0.01."/>
                <lightning:input type="checkbox" aura:id="itemform" label="Packed?"  
                                 name="itempacked"
                                 checked="{!v.newItem.Packed__c}"/>
                <lightning:button label="Create Item" 
                                  class="slds-m-top--medium"
                                  variant="brand"
                                  onclick="{!c.clickCreateItem}"/>
            </form>
            <!-- / CREATE NEW ITEM FORM -->
      
          </fieldset>
          <!-- / BOXED AREA -->
        </div>
        <!-- / CREATE NEW ITEM -->
        </lightning:layoutItem>
    </lightning:layout>
    
    <lightning:card title="Items">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="item">
                <c:campingListItem item="{!item}"/>
            </aura:iteration>
        </p>
    </lightning:card>
</aura:component>
3.campingListController.js
({
    clickCreateItem: function(component, event, helper) {
        var validItem = component.find('itemform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        // If we pass error checking, do some real work
        if(validItem){
            // Create the new item
            var newItem = JSON.parse(JSON.stringify(component.get("v.newItem")));
            var theItems = component.get("v.items");
            theItems.push(newItem);
            component.set("v.items", theItems);
            component.set("v.newItem",{'sobjectType':'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false});
        }
    }
})

4.campingHeader.cmp
<aura:component >
    <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem>
            <lightning:icon iconName="action:goal" alternativeText="My Items"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1>Camping List</h1>
                <h2 class="slds-text-heading--medium">My Items</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>    
</aura:component>

5.campingListItem.cmp
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c" required="true"/>
    <p>
    	Name: {!v.item.Name}
    </p>
    <p>
        Quantity: {!v.item.Quantity__c}
    </p>
    <p>
        Price: <lightning:formattedNumber style="currency" value="{!v.item.Price__c}"/>
    </p>
    <p>
    	Packed: {!v.item.Packed__c}
    </p>
    <p>
        <lightning:input type="toggle"
                         checked="{!v.item.Packed__c}"
                         name="packed"
                         label="Packed?"/>
    </p>
    <lightning:button label="Packed!" onclick="{!c.packItem}"/>
</aura:component>

6.campingListItemController.js
​​​​​​​
({
	packItem : function(component, event, helper) {
		var btn = event.getSource();
        btn.set("v.disabled", true);
        component.set("v.item.Packed__c", true);
	}
})
Dinesh RajursDinesh Rajurs

Hi Folks,
I struggled and spent hours on this module (until I googled out of desparation), the challenge kept failing even when the sample worked. Couple things I had to change.

1. Move the iterator logic from a custom component(abstraction) to the campingList.cmp component and then still had to make the changes suggested by @Augustin Rieunier (Big thanks)
2. Had to port the controller logic to add them items (put) from a helper function the the main controller JS file (uggg....). 

Hope the module creators will updated it to handle these nuanced issues.