0

I am trying to complete a Trailhead challenge (Input Data Using Form) and according to it if I pass an attribute from the parent to the child I should be able to access it and view all the properties. Here is what I am doing from the parent component -

<aura:component access="global">
<aura:attribute access="global" name="items" type="Camping_Item__c[]"></aura:attribute>
<aura:attribute name="newItem" type="Camping_Item__c" 
                default="{ 'sobjectType':'Camping_Item__c','Quantity__c':0, 
                         'Price__c':0 }">
</aura:attribute>
<!--Input Form-->
<lightning:layout >
    <form>
        <fieldset class="slds-box slds-theme--default slds-container--small">
            <legend id="newexpenseform" class="slds-text-heading--small 
              slds-p-vertical--medium">
              Add Item
            </legend>
            <lightning:layoutItem >
            <ol>
                <lightning:input aura:id="input" label="Camping Item Name"
                     name="Name"
                     value="{!v.newItem.Name}"
                     required="true"/> 
                <lightning:input name="Quantity"
                                 aura:id="input"
                                 value="{!v.newItem.Quantity__c}" 
                                 label="Quantity" 
                                 type="number" 
                                 min="1" 
                                 messageWhenRangeUnderflow="Quantity should be greater than 0"/>
                <lightning:input name="Price"
                                 aura:id="input"
                                 value="{!v.newItem.Price__c}" 
                                 label="Price"
                                 formatter="currency"/>
                <lightning:input name="Packed"
                                 type="checkbox"
                                 label="Packed"
                                 aura:id="input"
                                 checked="{!v.newItem.Packed__c}"/>
            </ol>
            </lightning:layoutItem>
            <lightning:layoutItem >
                <lightning:button class="slds-m-top--medium" label="Submit" 
                                  onclick="{!c.clickCreateItem}" variant="brand">
                </lightning:button>
            </lightning:layoutItem>
        </fieldset>
    </form>
    <!--Display Items-->
    {!items}
            <aura:iteration items="{!v.items}" var="item">
                <c:campingListItem item="{!item}"></c:campingListItem>
            </aura:iteration>
</lightning:layout> 

And here is the code for my child component -

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">
<aura:attribute name="item" type="Camping_Item__c" default="{ 
                                                            'sobjectType':'Camping_Item__c'
                                                            , 'Name':'Protien Bar',
                                                            'Packed__c':false ,
                                                            'Quantity__c':5,
                                                            'Price__c':25.0 }">
</aura:attribute>
<lightning:card title="Camping List">
    <p>{!v.item}</p>
    <p>Name : {!v.item.Name}</p>
    <p>Price : {!v.item.Price__c}</p>
    <p>Quantity : {!v.item.Quantity__c}</p>
    <p>Packed : {!v.item.Packed__c}</p>
    <p><lightning:formattedNumber value="{!v.item.Price__c}" style="currency"></lightning:formattedNumber></p>
    <p><lightning:formattedNumber value="{!v.item.Quantity__c}"></lightning:formattedNumber></p>
    <p><lightning:input name="Packed" label="Packed" type="toggle" checked="{!v.item.Packed__c}"></lightning:input></p>   
    <p><lightning:button label="Packed!" onclick="{!c.packItem}"></lightning:button></p>
</lightning:card>

The problem is it only shows me the value of {!v.item} that is the whole object and not the individual fields and I just cannot understand why. It also works when I use this component alone with a default value. Can anybody help me out?

Also adding the Javascript Controller -

({
clickCreateItem : function(component, event, helper) {
    var isValid=component.find("input").reduce( function( validSoFar,inputCmp){
        inputCmp.showHelpMessageIfInvalid();
        return validSoFar && inputCmp.get("v.validity").valid;
    }, true);
    if(isValid){
        console.log("working !");
        //Push newItem to items array
        var items=component.get("v.items");
        var newItem=JSON.stringify(component.get("v.newItem"));
        items.push(newItem);
        newItem="{'sobjectType':'Camping_Item__c','Name': '','Quantity__c': 0,'Price__c': 0,'Packed__c': false}";
        component.set("v.newItem",newItem);
        component.set("v.items",items);
    }
}

})

Here is the screenshot of the result enter image description here

4
  • Do you have the field values from the object populated appropriately in “items” variable?
    – Jayant Das
    Commented Apr 16, 2018 at 3:01
  • Yes, I am adding a screenshot for more detail. Commented Apr 16, 2018 at 7:32
  • How are you fetching the results from soql to populate the list of objects in parent component?
    – Jayant Das
    Commented Apr 16, 2018 at 10:06
  • Ah okay, so since this was an introductory chapter on trailhead, it doesn't have an apex controller, but rather we create the Camping Items from a form on the same page and add it to the Items attribute from the javascript controller. I will add the whole parent component code and the javascript controller code for clarity. Commented Apr 16, 2018 at 10:44

1 Answer 1

1

When you pass an object from one component to another you don't need to stringify the data. In your code you were Stringify the 'newItem' before adding it to the items list. which in turn was passed to your child component as a string rather than an object. This is why {!v.item.Name} was not working as it works only for object not String. hence it was printing blank. In your controller class, remove the Json.stringify. newItem=JSON.stringify(component.get("v.newItem")); -----> newItem=component.get("v.newItem").

3
  • Thank you for the advice.....it did help, I can't seem to see it in the parent controller too. Can you help me understand why? It doesn't make sense to me.....sorry I am new to lightning. Commented Apr 16, 2018 at 10:58
  • 1
    When you pass an object from one component to another you don't need to stringify the data. In your code you were Stringify the 'newItem' before adding it to the items list. which in turn was passed to your child component as a string rather than an object. This is why {!v.item.Name} was not working as it works only for object not String. hence it was printing blank. In your controller class, remove the Json.stringify. newItem=JSON.stringify(component.get("v.newItem")); -----> newItem=component.get("v.newItem").
    – Bhawna
    Commented Apr 16, 2018 at 17:54
  • Ah yes, wow....thank you so much ! Can you add this to you're answer so I can mark it as accepted. Commented Apr 17, 2018 at 10:28

You must log in to answer this question.

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