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
Mansi Gupta 13Mansi Gupta 13 

Stuck in trailhead - Lightning Components Basics

Challenge - Create a form to enter new items and display the list of items entered. To make our camping list look more appealing, change the campingHeader component to use the SLDS. Similar to the unit, style the Camping List H1 inside the slds-page-header. Modify the campingList component to contain an input form and an iteration of campingListItem components for displaying the items entered.
The component requires an attribute named items with the type of an array of camping item custom objects.
The component requires an attribute named newItem of type Camping_Item__c with default quantity and price values of 0.
The component displays the Name, Quantity, Price, and Packed form fields with the appropriate input component types and values from the newItem attribute.
The JavaScript controller checks to ensure that the Name, Quantity and Price values submitted are not null.
If the form is valid, the JavaScript controller pushes the newItem onto the array of existing items, triggers the notification that the items value provider has changed, and resets the newItem value provider with a blank sObjectType of Camping_Item__c.


My answer - 
<aura:component >
<aura:attribute name="items" type="Camping_Item__c[]"/>
<aura:attribute name="newitem" type="Camping_Item__c[]"  default="{ 'sobjectType': 'Camping_Item__c',
                   'Quantity__c'=0, 'Price__c'=0}"/>
 <p>Name:
        <ui:inputText value="{!v.newitem.name}"/>
    </p>    
  <p>Packed:
        <ui:inputCheckbox value="{!v.newitem.Packed__c}"/>
     
    </p>    
  <p>Price:
        <ui:inputCurrency value="{!v.newitem.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:inputNumber value="{!v.newitem.Quantity__c}"/>
    </p>
</aura:component>


Error -

Challenge Not yet complete... here's what's wrong: 
The campingList component isn't iterating the array of 'items' and creating 'campingListItem' components.

Please share the correct solution.
Mouhamed N'DIONGUEMouhamed N'DIONGUE
Hello,
For this challenge there is much more to do. For this error you're giving, seems like you're not displaying the inputed items.
Hint : You know something like this : 
<aura:iteration items="{!v.items}" var="itm">
                    <c:campingListItem item="{!itm}"/><br/>
                </aura:iteration>

If I give you more, it will be the solution and I am sure you want to find it yourself(more interesting)
Regards

Mouhamed
Shobhit SaxenaShobhit Saxena
For the rest you can try this code:
 
campingList Component code:
 
<aura:component >
	
    <aura:attribute name="newItem" type="Camping_Item__c"
     default="{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false }"/>
    
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    
    <ol>
    <li>Bug Spray</li>
    <li>Bear Repellant</li>
    <li>Goat Food</li>
    </ol>
    
    <!-- CREATE NEW ITEM FORM -->
    <form class="slds-form--stacked">

      <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputText aura:id="itemname" label="Name"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Name}"
                  required="true"/>
          </div>
     </div>

     <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputNumber aura:id="quantity" label="Quantity"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Quantity__c}"
                  required="true"/>

          </div>
      </div>

      <div class="slds-form-element">
          <div class="slds-form-element__control">
              <ui:inputCurrency aura:id="price" label="Price"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Price__c}"
                  />
          </div>
      </div>

      <div class="slds-form-element">
          <ui:inputCheckbox aura:id="packed" label="Packed?"
              class="slds-checkbox"
              labelClass="slds-form-element__label"
              value="{!v.newItem.Packed__c}"/>
      </div>

      <div class="slds-form-element">
          <ui:button label="Create Camping Item"
              class="slds-button slds-button--brand"
              press="{!c.clickCreateItem}"/>
      </div>

    </form>
    <!-- / CREATE NEW ITEM FORM -->
    
   

    <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="{!item}"/>
                </aura:iteration>
            </div>
        </section>
    </div>

</aura:component>

Controller code:
({
    clickCreateItem: function(component, event, helper) {

        // Simplistic error checking
        var validItem = true;

        // Name must not be blank
        var nameField = component.find("itemname");
        var itemname = nameField.get("v.value");
        if ($A.util.isEmpty(itemname)){
            validItem = false;
            nameField.set("v.errors", [{message:"Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        
        // Quantity must not be blank
        var quantityField = component.find("quantity");
        var quantity = nameField.get("v.value");
        if ($A.util.isEmpty(quantity)){
            validItem = false;
            quantityField.set("v.errors", [{message:"Quantity can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }

        var priceField = component.find("price");
        var price = priceField.get("v.value");
        if ($A.util.isEmpty(price)){
            validItem = false;
            priceField.set("v.errors", [{message:"Price can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }


        if(validItem){
            var newItem = component.get("v.newItem");
            console.log("Create item: " + JSON.stringify(newItem));
            //helper.createItem(component, newItem);
            //        var theItems = 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("Items before 'create': " + JSON.stringify(theItems));
		theExpenses.push(newItem);
		component.set("v.expenses", theItems);
		console.log("Items after 'create': " + JSON.stringify(theItems));
        theItems.push(newItem);
        component.set("v.items", theItems);
        
        }
    }
})

 
Shobhit SaxenaShobhit Saxena
And finally add the following piece of code at the bottom of your controller to get it done:
 
component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false }/>);

Do Mark this as best answer if you find it useful.
Ashutosh PradhanAshutosh Pradhan
1) The campingList Component Code:

<aura:component >
      <!-- <ol>
         <li>Bug Spray</li>
         <li>Bear Repellant</li>
         <li>Goat Food</li>
       </ol> -->
    <aura:attribute name="newItem" type="Camping_Item__c" required="true" default="{
                                                       'sobjectType': 'Camping_Item__c',
                                                          'Name': '',
                                                          'Quantity__c':0,
                                                           'Price__c':0,
                                                           'Packed__c':false }"/>
      <aura:attribute name="items" type="Camping_Item__c[]"/>
      
        
       
    
        <div aria-labelledby="newcampingform">
 
  <!-- BOXED AREA -->

  <fieldset class="slds-box slds-theme--default slds-container--small">
    <legend id="newexpenseform" class="slds-text-heading--small slds-p-vertical--medium">
      Camping
    </legend>
 

    <!-- CREATE NEW EXPENSE FORM -->
    <form class="slds-form--stacked">
      <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputText aura:id="name" label="Name"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Name}"
                  required="true"/>
          </div>
     </div>

     <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputNumber aura:id="quantity" label="Quantity" class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Quantity__c}"
                  required="true"/>

          </div>
      </div>
      <div class="slds-form-element">
          <div class="slds-form-element__control">
              <ui:inputText aura:id="price" label="Price"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Price__c}"
                  placeholder="100$."/>
          </div>
      </div>
      <div class="slds-form-element">
          <div class="slds-form-element__control">
          <ui:inputCheckbox aura:id="reimbursed" label="Packed?"
              class="slds-checkbox"
              labelClass="slds-form-element__label"
              value="{!v.newItem.Packed__c}"/>
      </div>
          
      </div>
      
      <div class="slds-form-element">
          <ui:button label="Packed!"
              class="slds-button slds-button--brand"
              press="{!c.clickCreateItem}"/>
      </div>
    </form>
    
  </fieldset>
  

      <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>

            
            
</div>
    
 

</aura:component>

2) The campingListItem component code
<aura:component >
     
     <aura:attribute name="item" type="Camping_Item__c" required="true" default=""/>
      <p>
        Name :<ui:outputText value="{!v.item.Name}"/>
        Quantity :<ui:outputNumber value="{!v.item.Quantity__c}"/> 
        Price :<ui:outputCurrency value="{!v.item.Price__c}"/>
        Packed:<ui:outputCheckbox value="{!v.item.Packed__c}"/>
      </p>
     
  </aura:component>

The controller will look like as follows:
({
    clickCreateItem : function(component, event, helper) {
                        // Simplistic error checking
        var validCamping = true;
        // Name must not be blank
        var nameField = component.find("name");
        var name = nameField.get("v.value");
        var quantityField = component.find("quantity");
        var quantity = nameField.get("v.value");
         var priceField = component.find("price");
        var price = nameField.get("v.value");

        if ($A.util.isEmpty(name)){
            validCamping = false;
            nameField.set("v.errors", [{message:"Camping name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        if ($A.util.isEmpty(quantity)){
            validCamping = false;
            nameField.set("v.errors", [{message:"Camping quantity can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        if ($A.util.isEmpty(price)){
            validCamping = false;
            nameField.set("v.errors", [{message:"Camping price can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        
       if(validCamping){
             var newItem = component.get("v.newItem");
             console.log("Create item: " + JSON.stringify(newItem));
            var newItems = component.get("v.items");
           newItems.push(JSON.parse(JSON.stringify(newItem)));
           component.set("v.items", newItems);
           component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                    'Price__c': 0,'Packed__c': false }/>);


       }
        
    }
})
Joseph HutchinsJoseph Hutchins
Hello,

I had the same issue and used Shobhit Saxena reponse to get a proper solution.  Please use this to understand whyyour challenge was not working.  There are three main files created/modified to get this to work:

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',
                               'Quantity__c' : 0,
                               'Price__c' : 0}"/>
  <!-- BOXED AREA -->
  <fieldset class="slds-box slds-theme--default slds-container--small">

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

    <!-- CREATE NEW CAMPING ITEM FORM -->
    <form class="slds-form--stacked">

      <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputText aura:id="campItemName" label="Camping Item Name"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Name}"
                  required="true"/>
          </div>
     </div>

     <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputNumber aura:id="quantity" label="Quantity"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Quantity__c}"
                  required="true"/>

          </div>
      </div>

      <div class="slds-form-element">
          <div class="slds-form-element__control">
              <ui:inputCurrency aura:id="price" label="Price"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Price__c}"/>
          </div>
      </div>

      <div class="slds-form-element">
          <ui:inputCheckbox aura:id="packed" label="Packed?"
              class="slds-checkbox"
              labelClass="slds-form-element__label"
              value="{!v.newItem.Packed__c}"/>
      </div>

      <div class="slds-form-element">
          <ui:button label="Create Camping Item"
              class="slds-button slds-button--brand"
              press="{!c.clickCreateItem}"/>
      </div>

    </form>
    <!-- / CREATE NEW CAMPING ITEM FORM -->

  </fieldset>
        <div class ="slds-card slds-p-top--meduim">
        <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>
    <!-- i do not think this html is needed any longer
	<ol>  
        <li>Bug Spray</li>
        <li>Bear Repellant</li>
        <li>Goat Food</li>
    </ol>-->
</aura:component>

campingController.cmp:
({
	clickCreateItem : function(component, event, helper) {
		
        var validItem = true;
        
        //  get and verify the name is set
        var nameField = component.find("campItemName");
        var campname = nameField.get("v.value");
        if ($A.util.isEmpty(campname))
        {
            validItem = false;
            nameField.set("v.errors", [{message: "Camping Item name can't be blank."}]);
        }
        else
        {
            nameField.set("v.errors", null);
        }
        
        //  check quantity
        var quantityField = component.find("quantity");
        var quantityValue = quantityField.get("v.value");
        if ($A.util.isEmpty(quantityValue) || quantityValue == 0)
        {
            validItem = false;
            quantityField.set("v.errors", [{message : "Quantity cannot be 0 or blank."}]);
        }
        else
        {
            quantityField.set("v.errors", null);
        }
        
        //  check price
        var priceField = component.find("price");
        var priceValue = priceField.get("v.value");
        if ($A.util.isEmpty(priceValue) || priceValue == 0)
        {
            validItem = false;
            priceField.set("v.errors", [{message : "Price cannot be 0 or blank."}]);
        }
        else
        {
            priceField.set("v.errors", null);
        }
        
        if (validItem)
        {
            //  gets refernce to view's newItem attribute
            var newItemRef = component.get("v.newItem");
            console.log("Create Camping Item: " + JSON.stringify(newItemRef));
            
            //helper.createItem(component, newItem);
            
            // **** begin helper class code ****
            // note that i originally created helper class to perform the logic below
            // but it appears as though the challenge is expecting you NOT to use helper class
            // which would be why i was getting challenge error while using it
            var theItems = component.get("v.items");
 
            // Copy the expense to a new object
            // THIS IS A DISGUSTING, TEMPORARY HACK
            var newItem = JSON.parse(JSON.stringify(newItemRef));    
            theItems.push(newItem);
            component.set("v.items", theItems);
            //  *******  end helper class code *********
            
            //  this will reset the view's newItem object 
            //  to a be a blank sobject of type Camping_Item__c
            //  credit to: Shobhit Saxena
            component.set("v.newItem", 
                          {'sobjectType' : 'Camping_Item__c',
                           'Name' : '',
                           'Quantity__c' : 0,
                           'Price__c' : 0,
                           'Packed__c' : false});
                           
        }
        
	}
})
campingItem.cmp:
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Packed?:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>


 
rahul seth 6rahul seth 6
I also got help from Shobhit Saxena's Code.He helped a lot!
Megan JobesMegan Jobes
Don't use a helper class in this one, that is what my problem was.
Andrés Cubillos 10Andrés Cubillos 10
thank you Shobhit
UgNderUgNder
Megan Jobes,

You can use controller helper. It's worked for me.
UgNderUgNder
Code for this task using contoller & helper.
  1. campingHeader.cmp
    <aura:component >
        
        <!-- PAGE HEADER -->
        <div class="slds-page-header" role="banner">
          <div class="slds-grid">
            <div class="slds-col">
              <p class="slds-text-heading--label">Campings</p>
              <h1 class="slds-text-heading--medium">Camping List</h1>
            </div>
          </div>
        </div>
        <!-- / PAGE HEADER -->
        
    </aura:component>
  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 }"/>
        
        <!-- NEW CAMPING FORM -->
            <div class="slds-col slds-col--padded slds-p-top--large">
                
                <div aria-labelledby="newcampingform">
                
                  <!-- BOXED AREA -->
                  <fieldset class="slds-box slds-theme--default slds-container--small">
                
                    <legend id="newcampingform" class="slds-text-heading--small 
                      slds-p-vertical--medium">
                      Add Camping
                    </legend>
                
                    <!-- CREATE NEW CAMPING FORM -->
                    <form class="slds-form--stacked">
                
                      <div class="slds-form-element slds-is-required">
                          <div class="slds-form-element__control">
                              <ui:inputText aura:id="campname" label="Camping Name"
                                  class="slds-input"
                                  labelClass="slds-form-element__label"
                                  value="{!v.newItem.Name}"
                                  required="true"/>
                          </div>
                     </div>
                
                     <div class="slds-form-element slds-is-required">
                          <div class="slds-form-element__control">
                              <ui:inputNumber aura:id="campQty" label="Quantity"
                                  class="slds-input"
                                  labelClass="slds-form-element__label"
                                  value="{!v.newItem.Quantity__c}"
                                  required="true"/>
                
                          </div>
                      </div>
                
                      <div class="slds-form-element">
                          <div class="slds-form-element__control">
                              <ui:inputText aura:id="campPrice" label="Price"
                                  class="slds-input"
                                  labelClass="slds-form-element__label"
                                  value="{!v.newItem.Price__c}"
                                  required="true"/>
                          </div>
                      </div>
                
                      <div class="slds-form-element">
                          <ui:inputCheckbox aura:id="campPacked" label="Packed"
                              class="slds-checkbox"
                              labelClass="slds-form-element__label"
                              value="{!v.newItem.Packed__c}"/>
                      </div>
                
                      <div class="slds-form-element">
                          <ui:button label="Create Camping"
                              class="slds-button slds-button--brand"
                              press="{!c.clickCreateCamping}"/>
                      </div>
                
                    </form>
                    <!-- / CREATE NEW CAMPING FORM -->
                
                  </fieldset>
                  <!-- / BOXED AREA -->
                
                </div>
                <!-- / CREATE NEW CAMPING -->
        
            </div>
    	<!-- / NEW CAMPING FORM -->
        
            <div class="slds-card slds-p-top--medium">
            <header class="slds-card__header">
                <h3 class="slds-text-heading--small">Camping</h3>
            </header>
            
            <section class="slds-card__body">
                <div id="list" class="row">
                    <aura:iteration items="{!v.items}" var="cmp">
                        <c:campingListItem item="{!cmp}"/>
                    </aura:iteration>
                </div>
            </section>
        </div>
    
    </aura:component>
  3. campingListController.js
    ({
        clickCreateCamping: function(component, event, helper) {
    
            // Simplistic error checking
            var validCamping = true;
    
            // Name must not be blank
            var nameField = component.find("campname");
            var campname = nameField.get("v.value");
            
            if ($A.util.isEmpty(campname)){
                validCamping = false;
                nameField.set("v.errors", [{message:"Camping name can't be blank."}]);
            }
            else {
                nameField.set("v.errors", null);
            }
            
            if ($A.util.isEmpty(component.find("campQty").get("v.value"))){
                validCamping = false;
                component.find("campQty").set("v.errors", [{message:"Camping Quantity can't be blank."}]);
            }
            else {
                component.find("campQty").set("v.errors", null);
            }
            if ($A.util.isEmpty(component.find("campPrice").get("v.value"))){
                validCamping = false;
                component.find("campPrice").set("v.errors", [{message:"Camping Price can't be blank."}]);
            }
            else {
                component.find("campPrice").set("v.errors", null);
            }
            
            
    
            // ... hint: more error checking here ...
    
            // If we pass error checking, do some real work
            if(validCamping){
                // Create the new expense
                var newCamping = component.get("v.newItem");
                console.log("Create Camping: " + JSON.stringify(newCamping));
                helper.createCamping(component, newCamping);
            }
        }
    })
  4. campingListHelper.js
    ({
        createCamping: function(component, item) {
            var theitems = component.get("v.items");
     
            var newitem = JSON.parse(JSON.stringify(item));
     
            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 });
        }
    })
  5. campingListItem.cmp
    <aura:component >
        <aura:attribute name="item" type="Camping_Item__c"/>
        
        <p>Name:
            <ui:outputText value="{!v.item.Name}"/>
        </p>
        <p>Price:
            <ui:outputCurrency value="{!v.item.Price__c}"/>
        </p>
        <p>Quantity:
            <ui:outputNumber value="{!v.item.Quantity__c}"/>
        </p>
        <p>Packed:
            <ui:outputCheckbox value="{!v.item.Packed__c}"/>
        </p>
    </aura:component>
manjunath.tjmanjunath.tj
Hey,

I am able to complete the form with the additional help from this post. But am still getting the error "The campingList controller isn't pushing a new item onto the array of items."

But if the array was empty, how would the form displays the data in the grid. Looks something wrong with the challenge evaluation. Has anyone got it passed in Trailhead?

Camping List
UgNderUgNder
manjunath,

Seems like you haven't used array attribute name as 'items' properly in your exercise.Trailhead verifies with mentioned names. 
Saroj KushwahaSaroj Kushwaha
hi  manjunath.tj

same error i was geting so i moved following block of code from  "campingListHelper.js" to  "campingListController.js"    instead of calling   helper function  like this "helper.createItem(component, newItem);"


  var action = component.get("c.saveItem");
    action.setParams({
        "item": newItem
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            var campingArray = component.get("v.items");
            campingArray.push(response.getReturnValue());
            component.set("v.items", campingArray);
            component.set("v.newItem",{ 'sobjectType': 
                                               'Camping_Item__c',
                                                          'Name': '',
                                                   'Quantity__c': 0,
                                                      'Price__c': 0,
                                                     'Packed__c': false });
        }
    });
    $A.enqueueAction(action);

may be the variables names are different for your code. But the main thing is that "campingArray.push(response.getReturnValue());" should be in controller which is pushing newItems to existing items.  let me know this works for u or not
Shamal JayShamal Jay
Saroj,
Can you provide all the contents of  your  campingListController.js?
Saroj KushwahaSaroj Kushwaha
Shamal
sure, here is the code for campingListController.js
 
({
doInit: function(component, event, helper) {
    var action = component.get("c.getItems");
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            component.set("v.items", response.getReturnValue());
        }
        else {  console.log("Failed with state: " + state);  }
    });
    $A.enqueueAction(action);
},
    
    
    clickCreateItem: function(component, event, helper) {

        // Simplistic error checking
        var validItem = true;

        // Name must not be blank
        var nameField = component.find("itemname");
        var itemname = nameField.get("v.value");
        if ($A.util.isEmpty(itemname)){
            validItem = false;
            nameField.set("v.errors", [{message:"Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }        
         // Quantity must be set, must be a positive number
    var quantityField = component.find("quantity");
    var quantity = quantityField.get("v.value");
    if ($A.util.isEmpty(quantity) || isNaN(quantity) || (quantity <= 0.0)){
        validExpense = false;
        quantityField.set("v.errors", [{message:"Enter a valid quantity."}]);
    }
    else {
        // If the amount looks good, unset any errors...
        quantityField.set("v.errors", null);
    }
         // Price must be set, must be a positive number
    var priceField = component.find("price");
    var price = priceField.get("v.value");
    if ($A.util.isEmpty(price) || isNaN(price) || (price <= 0.0)){
        validExpense = false;
        priceField.set("v.errors", [{message:"Enter a valid price."}]);
    }
    else {
        // If the amount looks good, unset any errors...
        priceField.set("v.errors", null);
    }               
        // 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 action = component.get("c.saveItem");
    action.setParams({
        "item": newItem
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            var campingArray = component.get("v.items");
            campingArray.push(response.getReturnValue());
            component.set("v.items", campingArray);
            component.set("v.newItem",{ 'sobjectType': 
                                               'Camping_Item__c',
                                                          'Name': '',
                                                   'Quantity__c': 0,
                                                      'Price__c': 0,
                                                     'Packed__c': false });
        }
    });
    $A.enqueueAction(action);
        }
    }           
})

 
Quang Tran NhatQuang Tran Nhat
Hi Saroj Kushwaha. Thank you for your effort, i pass this challenge.
Akshay DeshmukhAkshay Deshmukh
Hi Saroj,

This code worked for me. Actually challenge asks us to write logic in controller iteslef and not use helper at all (at least for this module).

1. CampingList.cmp
<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>
    
    <!-- NEW Campaing FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">
        
        
        <!-- [[ Campaing form goes here ]] -->
        
        <div aria-labelledby="newCampaingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Campaing FORM -->
                <form class="slds-form--stacked">
                    
                    <div class="slds-form-element slds-is-required">
                        <div class="slds-form-element__control">
                            <ui:inputText aura:id="campingName" label="Camping Name"
                                          class="slds-input"
                                          labelClass="slds-form-element__label"
                                          value="{!v.newItem.Name}"
                                          required="true"/>
                        </div>
                    </div>
                    
                    <div class="slds-form-element slds-is-required">
                        <div class="slds-form-element__control">
                            <ui:inputNumber aura:id="quantity" label="Quantity"
                                            class="slds-input"
                                            labelClass="slds-form-element__label"
                                            value="{!v.newItem.Quantity__c}"
                                            required="true"/>
                            
                        </div>
                    </div>
                    
                    
                    
                    <div class="slds-form-element">
                        <div class="slds-form-element__control">
                            <ui:inputCurrency aura:id="price" label="Price"
                                              class="slds-input"
                                              labelClass="slds-form-element__label"
                                              value="{!v.newItem.Price__c}"/>
                        </div>
                    </div>
                    
                    <div class="slds-form-element">
                        <ui:inputCheckbox aura:id="packed" label="Packed ?"
                                          class="slds-checkbox"
                                          labelClass="slds-form-element__label"
                                          value="{!v.newItem.Packed__c}"/>
                    </div>
                    
                    <div class="slds-form-element">
                        <ui:button label="Create Expense"
                                   class="slds-button slds-button--brand"
                                   press="{!c.createCampingList}"/>
                    </div>
                    
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
    
    <!-- ITERATIING ITEM LISTS -->
    <div class="slds-card slds-p-top--medium">
        
        <c:campingHeader/>
        
        <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>	
    <!-- / ITERATIING ITEM LISTS -->
    
    
    
</aura:component>

2. campingListController.js
({
    createCampingList : function(component, event, helper) {
        
        var isCampingValid = true;
        var nameField = component.find("campingName");
        var quantityField = component.find("quantity");
        var priceField = component.find("price");
        
        if(nameField.get("v.value") == '' ){
            nameField.set("v.errors",[{message:"name can't be blank"}]);
            isCampingValid = false;
        }
        else{
            nameField.set("v.errors",null);
        }
        
        
        if( quantityField.get("v.value") == '' ){
            quantityField.set("v.errors",[{message:"Quantity can't be blank"}]);
            isCampingValid = false;
        }
        else{
            quantityField.set("v.errors",null);
        }
        
        
        if(priceField.get("v.value") == ''){
            priceField.set("v.errors",[{message:"Price can't be blank"}]);
            isCampingValid = false;
        }
        else{
            priceField.set("v.errors",null); 
        }
        
        if(isCampingValid){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
        
        
        
    }
})

3. campingListItem.cmp (Used in campingList.cmp)
<aura:component implements="force:appHostable">
    <aura:attribute name="item" type="Camping_Item__c" />
    <p> <ui:outputText value="{!v.item.Name}"/> </p>
    <p>  <ui:outputCheckbox value="{!v.item.Packed__c}" /> </p>
    <p>  <ui:outputCurrency value="{!v.item.Price__c}"/> </p>
    <p>  <ui:outputNumber value="{!v.item.Quantity__c}"/> </p>
</aura:component>

4. campingHeader.cmp  (Used in campingList.cmp) 
<aura:component >
	
    <!-- PAGE HEADER -->
    <div class="slds-page-header" role="banner">
        <div class="slds-grid">
            <div class="slds-col">
                <h1 class="slds-text-heading--medium">Camping List</h1>
            </div>
        </div>
    </div>
    <!-- / PAGE HEADER -->
</aura:component>

This is  the simplest code which would pass the challenge and will work as well. Hope this will all.
Akshay DeshmukhAkshay Deshmukh
Adding order in which code should be copied to your dev orgs . Order  would be  - First copy code marked as no. 4, then 3 ,then 2 and then 1.

Thanks
Suzi Simmons 30Suzi Simmons 30
Thank you!!
isalewisalew
As Shobhit's code shows, and Saroj's reply emphasizes, the issue is that the challenge expects your code to be entirely in the controller, and not use any helper methods.

I successfully used a helper, but had to move code from the helper to the controller for trailhead to accept my work.
Amit GoyalAmit Goyal
you need to iterate the list of camping_item__c[] records at the bottom of you component. like this.

<div class="slds-card slds-p-top--medium">
        <header class="slds-card__header">
            <h3 class="slds-text-heading--small">Camping 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>
guna Sevugapperumal 9guna Sevugapperumal 9
You will get the error  "The campingList controller isn't pushing a new item onto the array of items", if you are pushing the item from a helper class. That does not mean your code is wrong. Move to code to controller

({
    clickCreateItem : function(component, event, helper) {
        // Simplistic error checking
        var validExpense = true;
        
        // validate name is not null
        var itemName = component.find("itemName").get("v.value");
        if($A.util.isEmpty(itemName)){
            validExpense = false;
            component.find("itemName").set("v.errors", [{message: "Expense name field cannot be empty"}]) ;
        }
        else{
            component.find("itemName").set("v.errors", null) ;
        }
        
        // validate price is not null
        var itemPrice = component.find("itemPrice").get("v.value");
        if($A.util.isEmpty(itemPrice)){
            validExpense = false;
            component.find("itemPrice").set("v.errors", [{message: "Expense price field cannot be empty"}]) ;
        }
        else{
            component.find("itemPrice").set("v.errors", null) ;
        }
        
        // Validate quantity is not null
        var itemQuantity = component.find("itemQuantity").get("v.value");
        if($A.util.isEmpty(itemQuantity)){
            validExpense = false;
            component.find("itemQuantity").set("v.errors", [{message: "Expense Quantity field cannot be empty"}]) ;
        }
        else{
            component.find("itemQuantity").set("v.errors", null) ;
        }
        
        // insert the expense record
        if(validExpense){
            var newItem = component.get("v.newItem");
            console.log("createItem" + JSON.stringify(newItem));
            
            
            // get the array variable
        var theItems = component.get("v.items");
        // Copy the expense to a new object
        var newItem = JSON.parse(JSON.stringify(newItem));
        // THIS IS A DISGUSTING, TEMPORARY HACK
         
        // Push the item to array variable
        theItems.push(newItem);
        // set the array variable
        component.set("v.items", theItems);
            
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false });
        }
    }
})
SUCHARITA MONDALSUCHARITA MONDAL

While creating new Camping Item, getting this error

This page has an error. You might just need to refresh it.

Assertion Failed!: Unknown controller action 'clickCreateItem' :

undefined Failing descriptor: {ui$button$controller$press}

 

Getting the above error while, creating new Camping Item. How to resolve it.

fajil tfajil t
Thank you soo much
Akshay Deshmukh
saroj
All of you guys
Rob AndersonRob Anderson
Thanks Shobhit
David Roberts 4David Roberts 4
Thanks to all for the help.Got a working solution. Now just need to understand why it didn't work for me in the first place. What a complicated excercise! Not using the helper really threw me.
KalyanGKalyanG
This was a bit tricky! 
Shubham Gupta 93Shubham Gupta 93
Always use 'item' as attribute name when iterating campinglistItem component in camping list.
 
<aura:component >

    <aura:attribute name="item" type="Camping_Item__c"/>

    <p>Name:
        <ui:outputtext value="{!v.item.Name}"/>
    </p>
    <p>Client:
        <ui:outputnumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Date:
        <ui:outputcurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Reimbursed?:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>

    

</aura:component>

 
Vigneshwaran GopalVigneshwaran Gopal

@shubham_gupta... You are right. that was my issue as well. But it's not fair, as they did not mention that we have to use 'item' as the attribute name for completing the exercise. Only the functionalities should be tested, not the names of the attributes. (I understand it's tricky though)

Time for Trailhead to get smarter.. Let's wait for Einstein to jump in with the power of AI :D

Javier Peña LucenaJavier Peña Lucena
since juno fo 2017, the campingItem.cmp must be:
<aura:component implements="force:appHostable">
    <aura:attribute name="item" type="Camping_Item__c" required="true" default="{Name:'Tent', Price__c:100, Quantity__c:1, Packed__c:false}"/>
    <p> <ui:outputText value="{!v.item.Name}"/> </p>
    <p>  <ui:outputCheckbox value="{!v.item.Packed__c}" /> </p>
    <p>  <ui:outputCurrency value="{!v.item.Price__c}"/> </p>
    <p>  <ui:outputNumber value="{!v.item.Quantity__c}"/> </p>
</aura:component>
required='true' + default values
Gbolahan JolapamoGbolahan Jolapamo
Hi guys,
My challenge isnt complete and heres whats wrong:
The campingList component doesn't appear to have a Quantity input field in the form using a Lightning Base component.

This is the form tag and its child components in my doccument. Can anyone correct. Thanks.

<form class="slds-form--stacked">
                    
                    <div class="slds-form-element slds-is-required">
                        <div class="slds-form-element__control">
                            <lightning:input aura:id="campingName" label="Camping Name"
                                          class="slds-input"
                                          value="{!v.newItem.Name}"
                                          required="true"/>
                        
                        </div>
                    </div>
                    
                    <div class="slds-form-element slds-is-required">
                        <div class="slds-form-element__control">
                            <lightning:input type="number" aura:id="quantity" label="Quantity"
                                            class="slds-input"
                                            value="{!v.newItem.Quantity__c}"
                                            required="true"/>
                            
                       </div>
                    </div>
                    
                    
                    
                    <div class="slds-form-element">
                        <div class="slds-form-element__control">
                            <lightning:input type="number" aura:id="price" label="Price"
                                              class="slds-input"
                                              value="{!v.newItem.Price__c}" formatter="currency"/>
                        </div>
                    </div>
                    
                    <div class="slds-form-element">
                        <lightning:input type="checkbox" aura:id="packed" label="Packed ?"
                                          class="slds-checkbox"
                                          value="{!v.newItem.Packed__c}"/>
                    </div>
                    
                    <div class="slds-form-element">
                        <lightning:button label="Create Expense"
                                   class="slds-button slds-button--brand"
                                   onclick="{!c.createCampingList}"/>
                    </div>
                    
                </form>
             
Francis CrumpFrancis Crump
as of september 2017 it requires lightning not ui for the form, so none of these solutions work anymore.  I did the form conversion but its requiring more than just this, but this will save someone else some time before I give up.

<!-- CREATE NEW Camping ITEM FORM -->
    <form class="slds-form--stacked">
       
        <lightning:input aura:id="itemform" label="Name"
                         name="Name"
                         value="{!v.newItem.Name}"
                         required="true"/>
                       
        <lightning:input aura:id="itemform" label="Item"
                         name="campingitem"
                         value="{!v.newCamping.Item__c}"/>
 
       
                <lightning:input type="number" aura:id="itemform" label="Quantity"
                         name="Quantity"
                         min="0"
                         formatter="number"
                         step="1"
                         value="{!v.newItem.Quantity__c}"
                         required="true"
                         messageWhenRangeUnderflow="Enter an amount that's at least 0"/>
 
                                                                <lightning:input type="number" aura:id="itemform" label="Price"
                         name="Price"
                         min="0.1"
                         formatter="currency"
                         step="0.01"
                         value="{!v.newItem.Price__c}"
                         messageWhenRangeUnderflow="Enter an amount that's at least $0.10."/>
 
                                                                                                 <lightning:input type="checkbox" aura:id="itemform" label="Packed?"
                         name="Packed"
                         checked="{!v.newItem.Packed__c}"/>
 
                                                                <lightning:button label="Packed!"
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
 
    </form>
 
salesforce snehalksalesforce snehalk
Below code worked for me:
//Component code starts
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c" required="true"
                    default="{Name:'Tent', Price__c:100, Quantity__c:1, Packed__c:false}"/>
    
    <P>Name: <ui:outputText value="{!v.item.Name}"/></P>   
    <p>
        <lightning:input type="toggle"                            
                         label="Packed?"                           
                         name="packed"                         
                         checked="{!v.item.Packed__c}" />
     </p>
    <p>Price:
        <lightning:formattedNumber value="{!v.item.Price__c}" style="currency"/>
    </p>
    <p>Quantity:
        <lightning:formattedNumber value="{!v.item.Quantity__c}" style="currency"/>
    </p>  
    
</aura:component>
//Component code finish

Thanks.
Francis CrumpFrancis Crump
I must have something messed up somewhere because that didnt' work for the trailhead either.  if you can post all of your code and all of the files with their names where the code goes, maybe I have a mislabeled or misnamed file or component? I have campingItem.cmp   campingListFormController.js campingListFormHelper.js  and campingListForm.cmp
Ender Reinoso SalazarEnder Reinoso Salazar
Hi,

I have this problem "The campingList JavaScript controller doesn't appear to be checking if form fields are valid."

I don't know what more I can validate to complete the challenge

This is my campingListContoller.js:
 
({
    clickCreateItem: function(component, event, helper) {

        // Simplistic error checking
        var validItem = true;

        // Name must not be blank
        var nameField = component.find("campname");
        var itemname = nameField.get("v.value");
        if ($A.util.isEmpty(itemname)){
            validItem = false;
            nameField.set("v.errors", [{message:"Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }        
         // Quantity must be set, must be a positive number
    	var quantityField = component.find("campquantity");
    	var quantity = quantityField.get("v.value");
    	if ($A.util.isEmpty(quantity) || (quantity < 1.0)){
        	validItem = false;
        	quantityField.set("v.errors", [{message:"Enter a valid quantity."}]);
    	}
    	else {
        	// If the amount looks good, unset any errors...
        	quantityField.set("v.errors", null);
    	}
        // Price must be set, must be a positive number
    	var priceField = component.find("campprice");
    	var price = priceField.get("v.value");
    	if ($A.util.isEmpty(price) || (price < 1.0)){
        	validItem = false;
        	priceField.set("v.errors", [{message:"Enter a valid price."}]);
    	}
    	else {
        	// If the amount looks good, unset any errors...
        	priceField.set("v.errors", null);
    	}          
        // ... hint: more error checking here ...

        // If we pass error checking, do some real work
        if(validItem){
            // Create the new item
            var newItem = component.get("v.newItem");
            console.log("Create Camping Item: " + JSON.stringify(newItem));         
            var campingItems = component.get("v.items");
            campingItems.push(JSON.parse(JSON.stringify(newItem));
        	component.set("v.items", campingItems);
        }
    }
})

 
Michal NowakMichal Nowak
I have the same problem as Ender, I'm also  checking isNAN() for price and quantity.
Akshay DeshmukhAkshay Deshmukh
Hello Ender Reinoso Salazar & Michal Nowak , Can you please try with my code above? Copy and Paste my code posted above into respective files. Let me know how it goes. Thanks, Akshay
Michal NowakMichal Nowak
Hello Akshay Deshmukh, after changing all UI Components in campingList and campingHeader to Base Lightning Components (cus atm the challenge requires it), the problem is still the same: The campingList JavaScript controller doesn't appear to be checking if form fields are valid.
Ender Reinoso SalazarEnder Reinoso Salazar
Hello Akshay, 

The challenge must had been updated, because in this moment I can't use "UI" components, I tried apply your validations in de Controller code and the error still appear.

Thanks.
Ender Reinoso SalazarEnder Reinoso Salazar
Hi Everybody,

I could finish the challenged with the help of another user, the code than I implement was
 
({
    clickCreateItem: function(component, event, helper) {

        // Simplistic error checking
         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 = component.get("v.newItem");
            console.log("Create Camping Item: " + JSON.stringify(newItem));         
            var campingItems = component.get("v.items");
            campingItems.push(JSON.parse(JSON.stringify(newItem));
        	component.set("v.items", campingItems);
            newItem = { 'sobjectType': 'Camping_Item__c', 'Quantity__c': 0, 'Price__c': 0 };
            component.set("v.newItem",newItem);
        }
    }
})

 
Gbolahan JolapamoGbolahan Jolapamo
Hi Michal,

I recently completed the exercise. Please let us know if your form validation is now okay. The call back provided by Ender appears pretty okay.

Thanks.
Michal NowakMichal Nowak
Hi Guys,

The code provided by Ender works perfect for me.

Thank you for help!
Akshay DeshmukhAkshay Deshmukh
Hi Nowak and Ender, glad that your code worked. I would check my code above to see if challenge has been updated or not. Thanks, Akshay
shubham_sonishubham_soni
Hello Guys,
For this challenge complete Follow This Code


if you complete challenge by this code so please like it


1.campingList.cmp
 
<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>
    
    <!-- NEW Campaing FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">
        
        
        <c:campingHeader/>
        
        <div aria-labelledby="newCampaingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Campaing FORM -->
                <form class="slds-form--stacked">
                    
                    <!-- For Name Field -->
        <lightning:input aura:id="expenseform" label="Camping Name"
                         name="expensename"
                         value="{!v.newItem.Name}"
                         required="true"/>
        <!-- For Quantity Field -->
        <lightning:input type="number" aura:id="campingform" label="Quantity"
                         name="expenseamount"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
         <!-- For Price Field -->
        <lightning:input aura:id="campingform" label="Price"
                         formatter="currency"
                         name="expenseclient"
                         value="{!v.newItem.Price__c}"
                          />
         <!-- For Check Box -->
        <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                         name="expreimbursed"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
    
    <!-- ITERATIING ITEM LISTS -->
    <div class="slds-card slds-p-top--medium">
        
        <c:campingHeader/>
        
        <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>    
    <!-- / ITERATIING ITEM LISTS -->
</aura:component>

2.campingListItem.cmp
 
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>

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

campingListController.js
 
({
    clickCreateItem : function(component, event, helper) {
    var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
            
        if(validCamping){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})

For Chacking Code Create A CampingApplication.app
<aura:application extends="force:slds">
    <c:campingList/>
</aura:application>
challenge complete
Reddeiah R 3Reddeiah R 3
shubham_soni! Great
Dev Pro 4Dev Pro 4
/* Hello Everyone, I have Completed This Challenge Successfully, Please Follow The Below Code. . . .*/
<!--------CampingList.cmp-------->

<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>
    
    <!-- NEW Campaing FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">
        
        <c:campingHeader/>
        
        <div aria-labelledby="newCampaingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Campaing FORM -->
                <form class="slds-form--stacked">
                    
                    <!-- For Name Field -->
        <lightning:input aura:id="expenseform" label="Camping Name"
                         name="expensename"
                         value="{!v.newItem.Name}"
                         required="true"/>
        <!-- For Quantity Field -->
        <lightning:input type="number" aura:id="campingform" label="Quantity"
                         name="expenseamount"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
         <!-- For Price Field -->
        <lightning:input aura:id="campingform" label="Price"
                         formatter="currency"
                         name="expenseclient"
                         value="{!v.newItem.Price__c}"
                          />
         <!-- For Check Box -->
        <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                         name="expreimbursed"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
    
    <!-- ITERATIING ITEM LISTS -->
    <div class="slds-card slds-p-top--medium">
        
        <c:campingHeader/>
        
        <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>    
    <!-- / ITERATIING ITEM LISTS -->
</aura:component>

<!--------CampingListItem.cmp-------->
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>

<!----------CampingHeader.cmp-------------------->

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

<!--------------CampingListController.js------------------>

({
    clickCreateItem : function(component, event, helper) {
    var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
            
        if(validCamping){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})

 
Yves Asselin 3Yves Asselin 3
Thank you Dev Pro 4 !!!!

Finally, 4 hours into a 35 minute question... and having lost half my hair as well as my confidence.... Your code worked perferfectly...

NOTE: I believe that the problem with the other answers is that Trailhead actually changed this module and left the old answers... 
Chetan KapaniaChetan Kapania
Hi Shubham and Dev Pro4,

I have tried the code mentioned in your thread, but I am getting error message as follows:
Challenge Not yet complete... here's what's wrong: 
The campingList component doesn't appear to have a Packed checkbox field in the form using a Lightning Base component.

While I am previewing Application, it is showing Packed component but not able to complete Trailhead challenge.

Regards
Chetan
Faiza Naz 10Faiza Naz 10
Hi,
You can get complete answer here.
​http://faizanaz90.blogspot.com/2017/11/lightning-components-basics-input-data.html
shashi kumar 58shashi kumar 58
Hi All,
Input Data Using Forms:--Lightning Components Basics

Follow the below Steps then you can clear your Challenge no#4
Step 1. CampingList.cmp

<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>
    
    <!-- NEW Campaing FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">
        
        
        <c:campingHeader />
        
        <div aria-labelledby="newCampaingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Campaing FORM -->
                <form class="slds-form--stacked">
                    
                    <!-- For Name Field -->
        <lightning:input aura:id="expenseform" label="Camping Name"
                         name="expensename"
                         value="{!v.newItem.Name}"
                         required="true"/>
        <!-- For Quantity Field -->
        <lightning:input type="number" aura:id="campingform" label="Quantity"
                         name="expenseamount"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
         <!-- For Price Field -->
        <lightning:input aura:id="campingform" label="Price"
                         formatter="currency"
                         name="expenseclient"
                         value="{!v.newItem.Price__c}"
                          />
         <!-- For Check Box -->
        <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                         name="expreimbursed"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
    
    <!-- ITERATIING ITEM LISTS -->
    <div class="slds-card slds-p-top--medium">
        
        <c:campingHeader />
        
        <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>    
    <!-- / ITERATIING ITEM LISTS -->
</aura:component>

Controller:--
Step 2:- CampingListController.js
({
    clickCreateItem : function(component, event, helper) {
    var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
            
        if(validCamping){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})

Step 3:- Create new lighting component
CampingListItem.cmp

<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>

Step 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 Camping"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping</h1>
                <h2 class="slds-text-heading--medium">My Camping</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
</aura:component>

Check your challenge :)


 
shashi kumar 58shashi kumar 58
Please follow the below steps easily you can clear Challenge 7

Lightning Components Basics
Connect Components with Events 

 
campingList.cmp

    <aura:component controller="CampingListController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes" >
<aura:attribute name="items" type="Camping_Item__c[]"/>


<aura:handler name="init" value="{!this}" action="{!c.doInit}" />     
<aura:handler name="addItem" event="c:addItemEvent" action="{!c.handleAddItem}"/>

 <div class="slds-grid">
    <div class="slds-col slds-col--padded sls-p-top--large">
        <c:campingListForm />
    </div>
</div>
<!-- ITERATING ITEM LISTS -->
<div class="slds-card slds-p-top--medium">

    <c:campingHeader />

    <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>  
<!-- / ITERATING ITEM LISTS -->
</aura:component>
Step 2:- Controller
({
    
    doInit: function(component, event, helper) {
    
        var action = component.get("c.getItems");
    
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.items", response.getReturnValue());
            }
            else {
                console.log("Failed with state: " + state);
            }
        });
    
        $A.enqueueAction(action);
    },    
    
    handleAddItem: function(component, event, helper) {
        var item = event.getParam("item");
                
        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 theItems = component.get("v.items");
                theItems.push(item);
                component.set("v.items",theItems);
            }
        });
        $A.enqueueAction(action);
    }
    
})


Step 2:- CampingListForm.cmp
<aura:component controller="CampingListController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes" >

    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>

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

    <div class="slds-col slds-col--padded slds-p-top--large">
        <div aria-labelledby="newCampaingForm">
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                    slds-p-vertical--medium">
                    Add Expense
                </legend>
                <!-- CREATE NEW Camping FORM -->
                    <div class="slds-col slds-col--padded slds-p-top--large">
        
        
        <c:campingHeader />
        
        <div aria-labelledby="newCampaingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Campaing FORM -->
                <form class="slds-form--stacked">
                    
                    <!-- For Name Field -->
        <lightning:input aura:id="expenseform" label="Camping Name"
                         name="expensename"
                         value="{!v.newItem.Name}"
                         required="true"/>
        <!-- For Quantity Field -->
        <lightning:input type="number" aura:id="campingform" label="Quantity"
                         name="expenseamount"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
         <!-- For Price Field -->
        <lightning:input aura:id="campingform" label="Price"
                         formatter="currency"
                         name="expenseclient"
                         value="{!v.newItem.Price__c}"
                          />
         <!-- For Check Box -->
        <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                         name="expreimbursed"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
            </fieldset>
            <!-- / BOXED AREA -->
        </div>
    </div>
</aura:component>



**Step 5:- CampingListFormController.js**
({    
    
    clickCreateCampingItem : function(component, event, helper) {
        
        var validCamping = true;

        // Name must not be blank
        var nameField = component.find("name");
        var expname = nameField.get("v.value");
        if ($A.util.isEmpty(expname)){
            validCamping = false;
            nameField.set("v.errors", [{message:"Camping Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }

        
        var priceField = component.find("price");
        var price = priceField.get("v.value");
        if ($A.util.isEmpty(price) || isNaN(price) || (price <= 0.0)){
            validCamping = false;
            priceField.set("v.errors", [{message:"Camping Item price can't be blank."}]);
        }
        else {
            priceField.set("v.errors", null);
        }
        
        var quantityField = component.find("quantity");
        var quantity = quantityField.get("v.value");
        if ($A.util.isEmpty(quantity) || isNaN(quantity) || (quantity <= 0)){
            validCamping = false;
            quantityField.set("v.errors", [{message:"Camping Item quantity can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }

        if(validCamping){
            
            helper.createItem(component);
            
        }
        
    },
})


**Step 6:-- CampingListItem.cmp**
 
<aura:component implements="force:appHostable">
    <aura:attribute name="item" type="Camping_Item__c" />
    <p>Name :
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Quantity :
        <ui:outputNumber value="{!v.item.Quantity__c}" />
    </p>
    <p>Price :
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Packed? :  
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>



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



**Step 8:--Apex Class:--campingListController.apxc**
public with sharing class CampingListController {

    @AuraEnabled 
    public static List<Camping_Item__c> getItems() {
        return [SELECT Id, Name, Price__c, Quantity__c, Packed__c FROM Camping_Item__c];
    }
    
    @AuraEnabled
    public static Camping_Item__c saveItem(Camping_Item__c item) {
        upsert item;
        return item;
    }
}



**Step 9:- campingListHelper.js**

should be empty

**Step 10 :- campingListItemController.js **
({
        
    packItem : function(component, event, helper) {
        var pack = component.get("v.item");
        pack.Packed__c = true;
        component.set("v.item",pack);
        var btnClicked = event.getSource();
        btnClicked.set("v.disabled",true);
        
    }
    
    
})


**Step 11:-add event :- addItemEvent.evt **
<aura:event type="COMPONENT">
    <aura:attribute name="item" type="Camping_Item__c"/>
</aura:event>
**Step 12 --CampingListFormHelper.js**
({
    
     createItem : function(component) {
        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});
    }
})

you can complete your challenge.. Please don't forget to like if you clear your challenge.


:)
MeetaGulatiMeetaGulati
https://trailhead.salesforce.com/projects/quickstart-lightning-components/steps/quickstart-lightning-components3?trailmix_creator_id=00550000006yDdKAAU&trailmix_id=prepare-for-your-salesforce-platform-app-builder-credential 

Did all steps + enabled domain in the process. I can see the component on the pagelayout. 

ERROR: 
There was an unhandled exception. Please reference ID: WXYSXYSZ. Error: Faraday::ClientError. Message: MALFORMED_QUERY: When retrieving results with Metadata or FullName fields, the query qualificatio​ns must specify no more than one row for retrieval. Result size: 2
arturo coronaarturo corona
hi everybody I pass the challege but I tried use my code and appears a error message like thisUser-added image
And i have the follow code:
campingList.cmp
<aura:component >
	<!--<ol>
        <li>Bug Spray</li>
        <li>Bear Repellant</li>
        <li>Goat Food</li>
    </ol>-->
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" 
                    default="{'sobjectType':'Camping_Item__c',
                             'Name': '',
                             'Price__c': 0,
                             'Quantity__c': 0,
                             'Packed__c': false}"/>
    <c:campingHeader/>
    <div aria-labelledby="newitemform">
        <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>
            <form class="slds-form--stacked">
                <lightning:input aura:id="itemForm" label="Item name" value="{!v.newItem.Name}" required="true" name="Item name"/>
                <lightning:input aura:id="itemForm" label="Quantity" type="number" value="{!v.newItem.Quantity__c}" min="1" name="Quantity"/>
                <lightning:input aura:id="itemForm" label="Price" type="number" formatter="currency" value="{!v.newItem.Price__c}" name="Price"/>
                <lightning:input aura:id="itemForm" label="Packed?" type="checkbox" checked="{!v.newItem.Packed__c}" name="Packed"/>
                <lightning:button label="Create item" class="slds-m-top--medium" variant="brand" onclick="{!c.clickCreateItem}"/>
            </form>
        </fieldset>
    </div>
    <div>
        <lightning:card title="List Items">
            <aura:iteration items="{!v.items}" var="itm">
                <c:campingListItem item="{!itm}"/>
            </aura:iteration>
        </lightning:card>
    </div>
</aura:component>
campingListController.js
({
	clickCreateItem : function(component, event, helper) {
        var validItem = component.find('itemform').reduce(function(validSoFar,inputCmp){
            inputComp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        },true);
        if(validItem){
            var newItem = component.get('v.newItem');
            var camping = component.get('v.items');
            var item = JSON.parse(JSON.stringify(newItem));
            camping.push(item);
            component.set("v.items",camping);
            component.set("v.newItem",{'sobjectType':'Camping_Item__c',
                             'Name':'',
                             'Price__c':0,
                             'Quantity':0,
                             'Packed__c': false});
        }
	}
})
what may be the failure?
ashish kumar 403ashish kumar 403
Hi everybody

Iff you are geting following error

Challenge Not yet complete... here's what's wrong: 
The campingList component isn't iterating the array of 'items' and creating 'campingListItem' components.

but your funtionality is working fine according to you then check the attribute name in camping list item.It has to be "item" only otherwise it will say error in iteration.

Thanks @Shubham Gupta93 for highlighting the trailhead mistake/bug
Asish BeheraAsish Behera
({
    clickCreateItem : function(component, event, helper) {
        var validCampaign = component.find('campaignform').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(validCampaign){
            // Create the new expense
            var newItem = component.get("v.newItem");
            console.log("Create expense: " + JSON.stringify(newItem));
            
        
            var items = component.get("v.items");
            items.push(newItem);
            component.set("v.items", items);
            component.set("v.newItem",{'sobjectType':'Camping_Item__c',
                             'Name':'',
                             'Price__c':0,
                             'Quantity':0,
                             'Packed__c': false});
            
        }
    }
})
BINOY MATHEWBINOY MATHEW
APPRECIATE EVERYONE who contributed to this. In mid June 2018, the Trailhead requires Lightning components instead of ui (as already stated by many). So I faced similar challenges. Plus other challenges. I made use of many different people's codes (due to errors in some) and figured how to get this correctly working (through trial and error) and also passing the challenge. Pasting below--->

Camping Header Component
-------------------------------------
<aura:component >
  <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="action:goal" alternativeText="My Camping"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping</h1>
                <h2 class="slds-text-heading--medium">My Camping</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
</aura:component>
==================================================================
CampingList Component
------------------------------------
<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>
    
    <!-- NEW Camping FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">
        
        <c:campingHeader/>
        
        <div aria-labelledby="newCampingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Camping FORM -->
                <form class="slds-form--stacked">
                    
                    <!-- For Name Field -->
        <lightning:input aura:id="expenseform" label="Camping Name"
                         name="expensename"
                         value="{!v.newItem.Name}"
                         required="true"/>
        <!-- For Quantity Field -->
        <lightning:input type="number" aura:id="campingform" label="Quantity"
                         name="expenseamount"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
         <!-- For Price Field -->
        <lightning:input aura:id="campingform" label="Price"
                         formatter="currency"
                         name="expenseclient"
                         value="{!v.newItem.Price__c}"
                          />
         <!-- For Check Box -->
        <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                         name="expreimbursed"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
    
    <!-- ITERATING ITEM LISTS -->
    <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>    
    <!-- / ITERATIING ITEM LISTS -->
</aura:component>
===========================================================
CampingList Controller
----------------------------------
({
    clickCreateItem : function(component, event, helper) {
    var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
            
        if(validCamping){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})
=========================================================
Camping List Item Component
-----------------------------
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c" required="true"/>
        
          <p>Name:<ui:outputText value="{!v.item.Name}"/>
              </p>
          <p>Price:<ui:outputCurrency value="{!v.item.Price__c}" />   
              </p>
          <p>Quantity:<ui:outputNumber value="{!v.item.Quantity__c}" />
               </p>
    
          <p>Packed:<ui:outputCheckbox value="{!v.item.Packed__c}"/>
                </p>
           <p>
            <lightning:input type="toggle"                            
                         label="Packed?"                           
                         name="Packed"                         
                         checked="{!v.item.Packed__c}" />
     </p> 
    <lightning:button label="Packed!"
            onclick="{!c.packItem}"/>
</aura:component>
=======================================================================

This should do it for you! Hopefully you don't kill too much time on this like me lol. 
Rahul.SharmaRahul.Sharma
Hi Mansi,
Do not use <ui:input> in your code. Instead of this, use Lightning base component. Pasting the code that will pass the challenge:

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

<-----------------CampingList Component---------------------------->
<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'}"/>
    
    <form class="slds-form--stacked">
        <lightning:input aura:id= "cmpform" label="Name" name= "itemname" value="{!v.newItem.Name}"/>
        
        <lightning:input aura:id= "cmpform" label="Quantity" name="itemquantity" 
                         value="{!v.newItem.Quantity__c}" type="number" min= "1"/>
        
        <lightning:input aura:id= "cmpform" label="Price" name="itemprice" value="{!v.newItem.Price__c}"
                         formatter="currency"/>
        
        <lightning:input type="checkbox" aura:id="cmpform" label="Packed?" 
                          checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Submit" onclick="{!c.clickCreateItem}"/>
        
    </form>
    
    <aura:iteration items="{!v.items}" var="itm">
                    <c:campingListItem item="{!itm}"/><br/>
                </aura:iteration>

    
</aura:component>

<------------------------------------------------------------------------------------------------->

<----------------------CampingList Controller---------------------------------------------->

({
    clickCreateItem : function(component, event, helper) {
        var validCamping = component.find("cmpform").reduce(
            function(validSoFar, inputCmp){
                inputCmp.showHelpMessageIfInvalid();
                return validSoFar && inputCmp.get('v.validity').valid;
            },true);
        
        if(validCamping){
        var newItem= component.get("v.newItem");
        var items = component.get("v.items");
        items.push(newItem);
        component.set("v.items", items);
            component.set("v.newItem", {'sObjectType' : 'Camping_Item__c', 'Name': '',
                                        'Price__c' : '0', 'Quantity__c' : '0', 'Packed__c' : 'false'});
        alert('New Item has been added!');
        }
        
    }
})

<-------------------------------------------------------------------------------------------------->

<----------------------CampingListItem component--------------------------------------->

<aura:component >
    <aura:attribute name="item" type="Camping_Item__c" required = "True"/>
       <p>Name: {!v.item.Name}</p>
    <p>Price: <lightning:formattedNumber value="{!v.item.Price__c}"
                                         style="currency"/></p>
    <p>Quantity: <lightning:formattedNumber value="{!v.item.Quantity__c}"    style="decimal"/></p>
    <p><lightning:input type="checkbox"
                        aura:id="toggleswitch"
                        label="Packed"
                        name="packed"
                        checked="{!v.item.Packed__c}"/></p>
    <lightning:button label="Packed!" 
                      onclick="{!c.packItem}"/>
    
</aura:component>

<---------------------------------------------------------------------------------------------------->

<-----------------------------CampingListItem Controller---------------------------------->

({
    packItem: function(component, event, helper) {
        var a = component.get("v.item",true);
        a.Packed__c = true;
        component.set("v.item",a);
        var btnClicked = event.getSource();
        btnClicked.set("v.disabled",true);
    }
})
<----------------------------------------------------------------------------------------------------->

Thanks and regards,
Rahul Sharma
 
Alikhan.ax1821Alikhan.ax1821
Hey, guys,

I've practically tried several pieces of the code above including Rahul's since it's the most recent, I keep getting this error:

Challenge not yet complete... here's what's wrong:
The campingHeader component doesn't appear to be using 'lightning:layout'.

I created the following:

campingList.cmp
campingListItem.cmp
camping.cmp
campingController.js
campingHeader.cmp
campingListController.js
campingListItemController.js

I created all the above by following suggestions from various folks on this thread so I may have created a few extra components :)

Thanks in advance!

Ali
Alikhan.ax1821Alikhan.ax1821
Ahh, figured this out, here's the correct campingHeader.cmp:

<aura:component >
  <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="action:goal" alternativeText="My Camping"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping</h1>
                <h2 class="slds-text-heading--medium">My Camping</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
</aura:component>
 
Aarooran Kanthasamy 1Aarooran Kanthasamy 1
----------------------------------
CAMPING APPLICATION  TO PREVIEW :
----------------------------------

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


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


---------------------------
CAMPING LIST COMPONENT:
---------------------------
<aura:component >
<aura:attribute name="items" type="Camping_Item__c[]"/>
<aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
'Quantity__c':0,
'Price__c':0,
'Packed__c':false,
'sobjectType':'Camping_Item__c'}"/>
 
<!-- NEW Campaing FORM -->
<div class="slds-col slds-col--padded slds-p-top--large">
 
 
<c:campingHeader/>
<div aria-labelledby="newCampaingForm">
 
<!-- BOXED AREA -->
<fieldset class="slds-box slds-theme--default slds-container--small">
 
<legend id="newCampaingForm" class="slds-text-heading--small
slds-p-vertical--medium">
Add Expense
</legend>
 
<!-- CREATE NEW Campaing FORM -->
<form class="slds-form--stacked">
 
<!-- For Name Field -->
    <lightning:input aura:id="expenseform" label="Camping Name"
name="expensename"
value="{!v.newItem.Name}"
required="true"/>
<!-- For Quantity Field -->
    <lightning:input type="number" aura:id="campingform" label="Quantity"
name="expenseamount"
min="1"
value="{!v.newItem.Quantity__c}"
messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
<!-- For Price Field -->
    <lightning:input aura:id="campingform" label="Price"
formatter="currency"
name="expenseclient"
value="{!v.newItem.Price__c}"
/>
<!-- For Check Box -->
    <lightning:input type="checkbox" aura:id="campingform" label="Packed"
name="expreimbursed"
checked="{!v.newItem.Packed__c}"/>
 
    <lightning:button label="Create Camping"
class="slds-m-top--medium"
variant="brand"
onclick="{!c.clickCreateItem}"/>
</form>
<!-- / CREATE NEW EXPENSE FORM --></fieldset>
<!-- / BOXED AREA -->
 
</div>
<!-- / CREATE NEW EXPENSE -->
</div>
<!-- ITERATIING ITEM LISTS -->
<div class="slds-card slds-p-top--medium">
 
<c:campingHeader/>
 
<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>
<!-- / ITERATIING ITEM LISTS -->
</aura:component>

------------------------------
CAMPING  CONTROLLER :
------------------------------

({
clickCreateItem : function(component, event, helper) {
var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
// Displays error messages for invalid fields
inputCmp.showHelpMessageIfInvalid();
return validSoFar && inputCmp.get('v.validity').valid;
}, true);
 
if(validCamping){
var newCampingItem = component.get("v.newItem");
//helper.createCamping(component,newCampingItem);
var campings = component.get("v.items");
var item = JSON.parse(JSON.stringify(newCampingItem));
 
campings.push(item);
 
component.set("v.items",campings);
component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
'Price__c': 0,'Packed__c': false });
}
}
})

---------------------------------------
CAMPING LIST ITEM COMPONENT:
---------------------------------------

<aura:component >
<aura:attribute name="item" type="Camping_Item__c"/>
 
Name:
<ui:outputText value="{!v.item.Name}"/>
 
Price:
<ui:outputCurrency value="{!v.item.Price__c}"/>
 
Quantity:
<ui:outputNumber value="{!v.item.Quantity__c}"/>
 
Packed:
<ui:outputCheckbox value="{!v.item.Packed__c}"/>
 
</aura:component>
Smita HodiggeriSmita Hodiggeri
@shubham_soni  Thanks Shubam.It helped me resolve my issue.
Evelyn MaguireEvelyn Maguire

Hello all! As of 12 March 2019, the <ui: ... > notation no longer clears the challenge.

This code isn't quite as pretty in terms of formatting as some of the code upthread, but this is what I used to pass the module.

CampingList.cmp:

<aura:component >
	<ol>
        <li>Bug Spray</li>
        <li>Bear Repellant</li>
        <li>Goat Food</li>
    </ol>
    
    <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}"/>
    
    <form class="slds-form--stacked">
        <div class="slds-form-element">   
            <lightning:input aura:id="campingForm"
                             name="Name" 
                             label="Name:" 
                             value="{!v.newItem.Name}"
                             required="true"/>
        </div>
        <div class="slds-form-element">
            <lightning:input aura:id="campingForm"
                             name="Quantity" 
                             type="number" 
                             min="1"
                             step="1"
                             label="Quantity:" 
                             value="{!v.newItem.Quantity__c}"
                             required="true"/>
        </div>
        <div class="slds-form-element">
            <lightning:input aura:id="campingForm"
                             name="Price" 
                             type="number" 
                             formatter="currency" 
                             label="Price:" 
                             value="{!v.newItem.Price__c}"
                             required="true"/>
        </div>
        <div class="slds-form-element">
            <lightning:input aura:id="campingForm"
                             name="Packed"
                             type="checkbox"
                             label="Packed?"
                             checked="{!v.newItem.Packed__c}"
                             required="true"/>
        </div>
        <div class="slds-form-element">
            <lightning:button variant="success" label="Submit" onclick="{!c.clickCreateItem}"/>
        </div>
    </form>
    
    <aura:iteration items="{!v.items}" var="item">
        <c:campingListItem item="{!item}"/>
    </aura:iteration>
                                            
</aura:component>

campingListController.js:

({
    clickCreateItem : function(component, event, helper) {
		var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
					// Displays error messages for invalid fields
					inputCmp.showHelpMessageIfInvalid();
					return validSoFar && inputCmp.get('v.validity').valid;
					}, true);
 
		if(validCamping){
			var newCampingItem = component.get("v.newItem");
			//helper.createCamping(component,newCampingItem);
			var campings = component.get("v.items");
			var item = JSON.parse(JSON.stringify(newCampingItem));
 
			campings.push(item);
 
			component.set("v.items",campings);
			component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
										'Price__c': 0,'Packed__c': false });
		}
	}
})
Ajay K DubediAjay K Dubedi
Hi Mansi,

This code will help you.
//campainList.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" >
    <aura:attribute name="items" type="Camping_Item__c[]" />
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Price__c': 0, 'Packed__c': false, 'Quantity__c': 0, 'Name':'Test', 'sobjectType': 'Camping_Item__c'}" />
    
    <lightning:layout>
        <lightning:layoutItem padding="around-small" size="6">
            <!-- CREATE NEW EXPENSE -->
            <div aria-labelledby="newCampingItem">
                <!-- BOXED AREA -->
                <fieldset class="slds-box slds-theme--default slds-container--small">
                    <legend id="newCampingItem" 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="campingItemForm" label="Name"
                                         name="itemName"
                                         value="{!v.newItem.Name}"
                                         required="true"/> 
                        
                        <lightning:input type="number" aura:id="campingItemForm" label="Quantity"
                                         name="itemQuantity"
                                         min="1"
                                         step="1"
                                         value="{!v.newItem.Quantity__c}"
                                         messageWhenRangeUnderflow="Enter the quantity atleast 1"/>
                        
                        <lightning:input type="number" aura:id="campingItemForm" label="Price"
                                         name="itemPrice"
                                         min="0.1"
                                         formatter="currency"
                                         step="0.01"
                                         value="{!v.newItem.Price__c}" />
                        
                        <lightning:input type="checkbox" aura:id="campingItemForm" 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 EXPENSE FORM -->
                    
                </fieldset>
                <!-- / BOXED AREA -->
            </div>
            <!-- / CREATE NEW EXPENSE -->
        </lightning:layoutItem>
        
        <lightning:layoutItem padding="around-small" size="6">
            <aura:Iteration items="{!v.items}" var="item">
                <c:campingListItem item="{!item}" />
            </aura:Iteration>
        </lightning:layoutItem>
    </lightning:layout>
    <!--
 <ol>
     <li>Bug Spray</li>
        <li>Bear Repellant</li>
        <li>Goat Food</li>
    </ol>
-->
</aura:component>


//campaingListController.js

({
    clickCreateItem : function(component, event, helper) {
        var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        
        if(validCamping){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})
//compaingHeader.cmp

<aura:component >
      <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</h1>
                <h2 class="slds-text-heading--medium">Camping List</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
</aura:component>


I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
Mohamed Arzad AliMohamed Arzad Ali
campingHeader.cmp
<aura:component >
  <lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="action:goal" alternativeText="My Camping"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping</h1>
                <h2 class="slds-text-heading--medium">My Camping</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
</aura:component>

CampingList.cmp
 
<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'Name':'',
                                                                   'Quantity__c':0,
                                                                   'Price__c':0,
                                                                   'Packed__c':false,
                                                                   'sobjectType':'Camping_Item__c'}"/>
    
    <!-- NEW Campaing FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">
        
        
        <c:campingHeader/>
        
        <div aria-labelledby="newCampaingForm">
            
            <!-- BOXED AREA -->
            <fieldset class="slds-box slds-theme--default slds-container--small">
                
                <legend id="newCampaingForm" class="slds-text-heading--small 
                                                   slds-p-vertical--medium">
                    Add Expense
                </legend>
                
                <!-- CREATE NEW Campaing FORM -->
                <form class="slds-form--stacked">
                    
                    <!-- For Name Field -->
        <lightning:input aura:id="expenseform" label="Camping Name"
                         name="expensename"
                         value="{!v.newItem.Name}"
                         required="true"/>
        <!-- For Quantity Field -->
        <lightning:input type="number" aura:id="campingform" label="Quantity"
                         name="expenseamount"
                         min="1"
                         value="{!v.newItem.Quantity__c}"
                         messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
         <!-- For Price Field -->
        <lightning:input aura:id="campingform" label="Price"
                         formatter="currency"
                         name="expenseclient"
                         value="{!v.newItem.Price__c}"
                          />
         <!-- For Check Box -->
        <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                         name="expreimbursed"
                         checked="{!v.newItem.Packed__c}"/>
        
        <lightning:button label="Create Camping" 
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreateItem}"/>
                </form>
                <!-- / CREATE NEW EXPENSE FORM -->
                
            </fieldset>
            <!-- / BOXED AREA -->
            
        </div>
        <!-- / CREATE NEW EXPENSE -->
    </div>
    
    <!-- ITERATIING ITEM LISTS -->
    <div class="slds-card slds-p-top--medium">
        
        <c:campingHeader/>
        
        <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>    
    <!-- / ITERATIING ITEM LISTS -->
</aura:component>

campingListController.js
 
({
    clickCreateItem : function(component, event, helper) {
    var validCamping = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
            
        if(validCamping){
            var newCampingItem = component.get("v.newItem");
            //helper.createCamping(component,newCampingItem);
            var campings = component.get("v.items");
            var item = JSON.parse(JSON.stringify(newCampingItem));
            
            campings.push(item);
            
            component.set("v.items",campings);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})

campingListItem.cmp
 
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>

hope it helps !​​​​​​​
Shureshh Gopu 7Shureshh Gopu 7
Thank you Mohamed Arzad Ali...Its worked perfectly
Samson AlwynSamson Alwyn
Could not find the 'Type_of_Installation__c' field on the custom object named 'Energy_Audit__c'.

IM getting this error in lightining experience-set up your org.....how to over come this error
madhu reddy 89madhu reddy 89
Hi am getting error "The campingList component isn't defining a handler correctly to listen for the addItemEvent event. The handler should listen for an addItemEvent event and then execute the action handleAddItem in the JavaScript controller. "User-added image
<aura:component controller="CampingListController">
	
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <aura:handler name="addItem" event="c:addItemEvent"
   	action="{!c.handleAddItem }"/>
    

    
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    
    <ol>
    <li>Bug Spray</li>
    <li>Bear Repellant</li>
    <li>Goat Food</li>
    </ol>
    
       <!-- NEW ITEM FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large">

        <c:campingListForm />

    </div>
    <!-- / NEW ITEM FORM -->    
   

    <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="{!item}"/>
                </aura:iteration>
            </div>
        </section>
    </div>

</aura:component>
 
({
    // Load 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 (component.isValid() && 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) {
    //   var newItem = event.getParam("item");
    //helper.addItem(component, newItem);
    var action = component.get("c.saveItem");
    		action.setParams({"item": newItem});
    		action.setCallback(this, function(response){
        		var state = response.getState();
        		if (component.isValid() && state === "SUCCESS") {
            		// all good, nothing to do.
            var items = component.get("v.items");
            items.push(response.getReturnValue());
            component.set("v.items", items);
        		}
    		});
    		$A.enqueueAction(action);
        		}
    
              
})
 
({
   addItem: function(component, item) {
    this.saveItem(component, item, function(response){
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            // all good, nothing to do.
         /*   var items = component.get("v.items");
            items.push(response.getReturnValue());
            component.set("v.items", items);*/
        }
    });
},
})
 
<aura:component >
	
        <aura:attribute name="newItem" type="Camping_Item__c"
     default="{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false }"/>
    <aura:registerEvent name="addItem" type="c:addItemEvent"/>
        <!-- CREATE NEW ITEM FORM -->
    <form class="slds-form--stacked">

      <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputText aura:id="itemname" label="Name"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Name}"
                  required="true"/>

          </div>
     </div>

     <div class="slds-form-element slds-is-required">
          <div class="slds-form-element__control">
              <ui:inputNumber aura:id="quantity" label="Quantity"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Quantity__c}"
                  required="true"/>

          </div>
      </div>

      <div class="slds-form-element">
          <div class="slds-form-element__control">
              <ui:inputCurrency aura:id="price" label="Price"
                  class="slds-input"
                  labelClass="slds-form-element__label"
                  value="{!v.newItem.Price__c}"
                  />
          </div>
      </div>

      <div class="slds-form-element">
          <ui:inputCheckbox aura:id="packed" label="Packed?"
              class="slds-checkbox"
              labelClass="slds-form-element__label"
              value="{!v.newItem.Packed__c}"/>
      </div>

      <div class="slds-form-element">
          <ui:button label="Create Camping Item"
              class="slds-button slds-button--brand"
              press="{!c.submitForm}"/>
      </div>

    </form>
    <!-- / CREATE NEW ITEM FORM -->
</aura:component>
 
({
    
    submitForm: function(component, event, helper) {    
    if(helper.validateItemForm(component)){
        // Create the new item
        var newItem = component.get("v.newItem");
        helper.createItem(component, newItem);
    }
        
        }

})
 
({
 addItem: function(component, newItem) {
    var addItem = component.getItem("addItem");
    addItem.setParams({ "item": item });
    addItem.fire();
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false } );
},
    

		validateItemForm: function(component) {
		
              // Simplistic error checking
        var validItem = true;

        // Name must not be blank
        var nameField = component.find("itemname");
        var itemname = nameField.get("v.value");
        if ($A.util.isEmpty(itemname)){
            validItem = false;
            nameField.set("v.errors", [{message:"Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        
        // Quantity must not be blank
        var quantityField = component.find("quantity");
        var quantity = nameField.get("v.value");
        if ($A.util.isEmpty(quantity)){
            validItem = false;
            quantityField.set("v.errors", [{message:"Quantity can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }
		// Price must not be blank
        var priceField = component.find("price");
        var price = priceField.get("v.value");
        if ($A.util.isEmpty(price)){
            validItem = false;
            priceField.set("v.errors", [{message:"Price can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }
            return (validItem);

	}
})
 
<aura:event type="COMPONENT">
    <aura:attribute name="item" type="Camping_Item__c"/>
</aura:event>

 
Chetan KapaniaChetan Kapania
Thank you Mohamed Arzad Ali...Its worked perfectly
AVINASH NAIR 7AVINASH NAIR 7
Thanks @Mohamed Arzad Ali......It worked perfectly
Ashish TawareAshish Taware

Mohamed Arzad Ali thanks much..

it works finally..
Deep898747Deep898747
Many Thanks to Mohamed Arzad Ali.
Yogesh MeltyYogesh Melty
This can help you.
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</h1>
                <h2 class="slds-text-heading--medium">My Camping</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
    <H1> <c:campingList/> </H1>
</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': '',
                        'Quantity__c': 0,
                        'Price__c': 0,
                        'Packed__c': ''}"/>
    <div aria-labelledby="newcampingform">
        <fieldset class="slds-box slds-theme--default slds-container--small">
  
        <form class="slds-form--stacked">          
            <lightning:input aura:id="campingform" label="Name"
                             name="name"
                             value="{!v.newItem.Name}"
                             required="true"/> 
            <lightning:input type="number" aura:id="campingform" label="Quantity"
                             name="quantity"
                             min="1"
                             formatter="Number"
                             step="1"
                             value="{!v.newItem.Quantity__c}"
                             messageWhenRangeUnderflow="Enter a quantity that's at least 1."/>
            <lightning:input aura:id="campingform" label="Price"
                             name="price"
                             formatter="currency" 
                             value="{!v.newItem.Price__c}"
                             />
            <lightning:input type="checkbox" aura:id="campingform" label="Packed"  
                             name="packed"
                             checked="{!v.newItem.Packed__c}"/>
            <lightning:button label="Create Item" 
                              class="slds-m-top--medium"
                              variant="brand"
                              onclick="{!c.clickCreateItem}"/>
        </form>
      </fieldset>
    </div>
    <div>
    <aura:iteration items="{!v.items}" var="item">
        <c:campingListItem item="{!item}"/>
    </aura:iteration>
    </div>
</aura:component>
CampingListController.js
({
    clickCreateItem : function(component, event, helper) {
        var validItem = component.find('campingform').reduce(function (validSoFar, inputCmp) {
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        if(validItem){
            var newI = component.get("v.newItem");
            var theItems = component.get("v.items");
            var Item = JSON.parse(JSON.stringify(newI));
            theItems.push(Item);
            component.set("v.items", theItems);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c','Name': '','Quantity__c': 0,
                                       'Price__c': 0,'Packed__c': false });
        }
    }
})

 
Sayi GodasiSayi Godasi
very helpful.. thanks!
Suraj Tripathi 47Suraj Tripathi 47

hi Mansi Gupta 13

I am Sharing Link. Please check 


https://github.com/Mulodo-Salesforce-Training/trailhead-salesforce-challenge/blob/master/LightningComponentForm.md
https://techevangel.com/2018/04/15/trailhead-challenge-create-a-form-to-enter-new-items/
 



Please mark it as Best Answer so that it can help others in the future.
Thanks 
Suraj Tripathi