• Sumanta Mukherjee 14
  • NEWBIE
  • 0 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 1
    Replies
While working on the trailhead challenge "Connect Components with Events" I am getting this error - "The campingList component isn't iterating the array of items and creating campingListItem components."
Here is my code.

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

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

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

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

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

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

7) campingListFormController.js​​​​​​​
​​​​​​​
({
    //Create new camping item
	submitForm : function(component, event, helper) {
        
        var isFormValid = component.find("newitemform").reduce(function(validSoFar, inputCmp){
            // Displays error messages for invalid fields
        	inputCmp.showHelpMessageIfInvalid();    	
            return validSoFar && inputCmp.get("v.validity").valid;
        });
        
        if (isFormValid) {
            
            var newCampingItem = component.get("v.newItem");
            helper.createItem(component, newCampingItem);
           
        }
	}
})
8) campingListFormHelper.js
({
     createItem : function(component) {
                       
        var action = component.get("c.saveItem");
        action.setParams({
            "item": item
        });
        
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {        
                var items = component.get("v.items");
                items.push(item);
                component.set("v.items",items);
            }
        });
        $A.enqueueAction(action);
         
        var item = event.getParam("item");
        var newItem = component.get("v.newItem");
        var addEvent = component.getEvent("addItem");
        addEvent.setParams({"item" : newItem});
        addEvent.fire();
        /*component.set("v.newItem",
                     { 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Packed__c': false,
                    'Price__c': 0,
                    'Quantity__c': 0});*/
    }
    
    
})
9) campingListController.apxc
public with sharing class CampingListController {
    @AuraEnabled
    public static List<Camping_Item__c> getItems() {
		List<Camping_Item__c> campingItems = [SELECT Id,Name,Price__c,Packed__c,Quantity__c FROM Camping_Item__c];
        return campingItems;
    }
    
    @AuraEnabled
    public static Camping_Item__c saveItem(Camping_Item__c campingItem) {
        upsert campingItem;
        return campingItem;
    }
}

10) addItemEv​​​​​​​ent.evt​​​​​​​​​​​​​​​​​​​​​​​​​​​​
<aura:event type="COMPONENT">
    <aura:attribute name="item" type="Camping_Item__c"/>
</aura:event>

​​​​​​​
Hi,

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

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

Here is my code:

a) harnessApp.app

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

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

b) campingHeader.cmp

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

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

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

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

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

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

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

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

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

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

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

d) campingListController.js

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

e) campingListHelper.js

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

f) campingListItem.cmp

<aura:component >

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

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

g) campingListItems.cmp

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


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

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

Thanks in advance for your assistance on this.