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
Douglas GDouglas G 

Lightning Components Basics, Handle Actions with Controllers - Issue with Challenge

Hey,

Thought I had understood all this fine but cant get the challenge to pass. Im going slowl mad and have probably made a dumb error. 

What am I doing wrong, or is the challenge broken? Any help much appreciated. 
The error I get is
Challenge Not yet complete... here's what's wrong: 
The campingListItem JavaScript controller isn't setting the 'item' attribute correctly.
My 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>Date:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed?:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
    <ui:button label="Packed!" press="{!c.packItem}" />
</aura:component>
My controller
({
	packItem : function(component, event, helper) {
        component.set("v.item.Packed__c", true);
        //console.log( JSON.stringify("v.item"));
        event.getSource().set("v.disabled" ,true);
	}
})









 
Jeff DouglasJeff Douglas
Douglas,

You need to update the item value provider. Add this line to your controller:
 
component.set("v.item", item);

Jeff Douglas
Trailhead Developer Advocate
Douglas GDouglas G
Great that works thanks! 

Makes sense, just a bit more involved than the examples in the module. 

Im a litte surprised that updating the Packed__c attribure of the item isnt enough and that you also need to explicitly update the item value provider as well. 

Onwards and upwards....
Martin Cadman 2016Martin Cadman 2016
Colour me confused. 

While adding the line above allows the challenge to pass, what does 'item' refer to? Is there another way to say 'updates the item value provider', because what is actually being asked for isn't clear to me.

I now get an error on execution, one that I more or less predicted I would get:

Looks like there's a problem:
Something has gone wrong. Action failed: c$campingListItem$controller$packItem [ReferenceError: item is not defined] Failing descriptor: {c$campingListItem$controller$packItem}. Please try again.

User-added image
Tomislav StrelarTomislav Strelar
Hmm, it looks to me (and please correct me if I got this all wrong) that directly updating the property of an item attribute doesn't update the value provider, so it is necesarry to get the item object, update its properties in javascript and then update the value provider by setting the attribute.

So:
var item = component.get("v.item");
item.Packed__c = true;
component.set("v.item", item);

I can't tell you that this is the correct way to do it, but it does makes sense and it passes the challenge.

Martin, I am as confused as you are if the code that you posted also allows the challenge to pass. 
dev0 - Artem Moshkedev0 - Artem Moshke
I had the same controller as what Douglas posted, and what did it for me was adding 
component.set("v.item", "{!v.item}");
after reading Tomislav's comment. Still not clear why it's necessary, but I am guessing it will make more sense once I learn how to populate the attributes with actual data.
dev0 - Artem Moshkedev0 - Artem Moshke
...and, as I suspected, it's needed to trigger the update notifications, as explained in the next section:
 
"What component.set() does here isn’t update the value of the expenses attribute. It triggers notification that the expensesattribute has changed.
The effect is that, anywhere in your app that you’ve referenced the expenses attribute in an expression, the value of that expression is updated, and that update cascades everywhere the expensesattribute was used. And they all update to rerender based on the new contents. This all happens behind the scenes, handled by the Lightning Components framework, as part of the auto-wiring that happens when you use {!v.expenses}. In a word, magic."

I'm guessing the reason they're asking you to do it there is because the challenge validation probably triggers off of that update as well. Although it's still kind of confusing to ask you to do something first and then explain how and why you're actually supposed to do it.
dev0 - Artem Moshkedev0 - Artem Moshke
Ok, so I got to the point where I actually get to use the component (the input forms challenge), and it turns out that
component.set("v.item", "{!v.item}");
does not do what I assumed it would do (assign the object to itself).

I'm not quite clear what it is that it does do, exactly, but it looks like it assigns a blank instance of the object to the variable instead (effectively destroying the data).

I.e. it probably shouldn't be passing the challenge.

Tomislav's solution appears to work, however (it properly sets the field to Packed the list at the bottom of the form).