You need to sign in to do that
Don't have an account?
Tavva Sai Krishna
Connect to Salesforce with Server-Side Controllers - Lightning Component Basics.
Hi All , getting the error while completing this module. While my application is running correctly.
Error: Challenge Not yet complete... here's what's wrong: The campingList JavaScript helper isn't saving the new record to the database or adding it to the 'items' value provider.
I am copying code for the finding the bug.
Apex Class:
CampingListHelper.js
campingListItem.js
Help me out with it.
Thanks and Regards,
Sai Krishna Tavva.
Error: Challenge Not yet complete... here's what's wrong: The campingList JavaScript helper isn't saving the new record to the database or adding it to the 'items' value provider.
I am copying code for the finding the bug.
Apex Class:
public class CampingListController { @auraenabled public static List<Camping_Item__c> getItems (){ List<Camping_Item__c> CI = [select id, name,price__c,Quantity__c,Packed__c from Camping_Item__c ]; return CI; } @auraenabled public static Camping_Item__c saveItem (Camping_Item__c CampingItem){ insert campingItem; return campingItem; } }CampingList.cmp
<aura:component controller="CampingListController"> <aura:handler name = "init" value="{!this}" action = "{!c.doInit}"/> <aura:attribute name="items" type="Camping_Item__c[]"/> <aura:attribute name="er" type="boolean" default="false"/> <aura:attribute name="newItem" type="Camping_Item__c" default="{ 'sobjectType': 'Camping_Item__c', 'Name': '', 'Price__c': 0, 'Quantity__c': 0, 'Packed__c': false }"/> <ui:inputText value="{!v.newItem.Name}" aura:id="name" label="name"/> <ui:inputCheckbox value="{!v.newItem.Packed__c}" aura:id="Packed" label="Packed"/> <ui:inputCurrency value="{!v.newItem.Price__c}" aura:id="Price" label="Price"/> <ui:inputNumber value="{!v.newItem.Quantity__c}" aura:id="Quantity" label="Quantity"/> <ui:button label="Create Expense" press="{!c.CreateCamping}" aura:id="button"/> <br/> <aura:iteration items="{!v.items}" var="PerItem"> <c:campingListItem item="{!PerItem}" /> </aura:iteration> </aura:component>CampingList.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()); } }); $A.enqueueAction(action); }, CreateCamping : function(component, event, helper){ helper.validateFields (component,component.find("name")); helper.validateFields (component,component.find("Price")); helper.validateFields (component,component.find("Quantity")); if(component.get("v.er") === false) { var lstItems = component.get("v.items"); var Item = component.get("v.newItem"); console.log('Before:'+lstItems); lstItems.push(Item); helper.CreateCampaign(component,Item); component.set("v.items",lstItems); console.log('After:'+lstItems); component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c', 'Name': '', 'Quantity__c': 0, 'Price__c': 0, 'Packed__c': false }); } } })
CampingListHelper.js
({ validateFields : function (component,field) { var nameField = field; console.log('yes:'+nameField); var expname = nameField.get("v.value"); if ($A.util.isEmpty(expname)){ component.set("v.er",true); nameField.set("v.errors", [{message:"this field can't be blank."}]); } else { nameField.set("v.errors", null); } }, CreateCampaign : function (component,Item){ var action = component.get("c.saveItem"); action.setParams({"CampingItem":Item}); action.setCallback(this,function(response){ var state = response.getState(); if (component.isValid() && state === "SUCCESS") { console.log('save'); } }); $A.enqueueAction(action); } })campingListItem.cmp
<aura:component > <aura:attribute type="Camping_Item__c" name="item" required="true"/> Name: <ui:outputText value="{!v.item.Name}" /><br/> Packed: <ui:outputCheckbox value="{!v.item.Packed__c}" /><br/> Price: <ui:outputCurrency value="{!v.item.Price__c}" /><br/> Quantity: <ui:outputNumber value="{!v.item.Quantity__c}" /><br/> <ui:button label="Packed!" press="{!c.packItem}" aura:id = "Button"/> <br/> </aura:component>
campingListItem.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); } })
Help me out with it.
Thanks and Regards,
Sai Krishna Tavva.
Thanks for your quick response. However the error is not with the js variable name . I have shifted the some code from CampingList.js to CampinListHelper.js . Now i completed the challenge. See the below updated code.
CampingList.js CampingListHelper.js
Thanks and Regards,
Sai Krishna Tavva.
All Answers
Jeff Douglas
Trailhead Developer Advocate
Try changing 'lstItems' for 'items' in lines #26, #29 and #31 in CampingList.js
It worked for me! Let me know if it helps you!
Regards.
Thanks for your quick response. However the error is not with the js variable name . I have shifted the some code from CampingList.js to CampinListHelper.js . Now i completed the challenge. See the below updated code.
CampingList.js CampingListHelper.js
Thanks and Regards,
Sai Krishna Tavva.
You can follow this link for your reference.
https://developer.salesforce.com/forums/ForumsMain?id=906F0000000kDPpIAM
Regards,
Sai Krishna Tavva.
Jeff Douglas
Trailhead Developer Advocate
Secondly, the helper did not appear to change anything. It received the information, but did nothing with it. That was all completed in the non-helper .js file. That could explain the error message:
"Error: Challenge Not yet complete... here's what's wrong: The campingList JavaScript helper isn't saving the new record to the database or adding it to the 'items' value provider."
had a problem with the set params function for the action - i was using different name for the signature where calling the apex controller.
another problem was that updating view method block should have be placed in the helper and used only when the component is valid and and the response status is "SUCCESS"
====================================================================
camping.cmp:
<aura:component >
<c:campingHeader />
<c:campingList />
</aura:component>
=================================================================
campingHeader.cmp
<aura:component >
<lightning:layout class="slds-page-header slds-page-header--object-home">
<lightning:layoutItem >
<lightning:icon iconName="action:goal" size="large" alternativeText="My Camping List"/>
</lightning:layoutItem>
<lightning:layoutItem padding="horizontal-small">
<div class="page-section page-header" role="banner">
<p class="slds-text-heading--label">Campings</p>
<h1 class="slds-text-heading--label">Camping List</h1>
</div>
</lightning:layoutItem>
</lightning:layout>
</aura:component>
==========================================================================
campingList.cmp
<aura:component controller="CampingListController">
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="items" type="Camping_Item__c[]"/>
<aura:attribute name="er" type="boolean" default="false"/>
<aura:attribute name="newItem" type="Camping_Item__c" default="{ 'sobjectType': 'Camping_Item__c',
'Name': '',
'Price__c': 0,
'Quantity__c': 0,
'Packed__c': false
}"/>
<ui:inputText value="{!v.newItem.Name}" aura:id="name" label="name"/>
<ui:inputCheckbox value="{!v.newItem.Packed__c}" aura:id="Packed" label="Packed"/>
<ui:inputCurrency value="{!v.newItem.Price__c}" aura:id="Price" label="Price"/>
<ui:inputNumber value="{!v.newItem.Quantity__c}" aura:id="Quantity" label="Quantity"/>
<ui:button label="CreateItem" press="{!c.CreateCamping}" aura:id="button"/>
<br/>
<aura:iteration items="{!v.items}" var="PerItem">
<c:campingListItem item="{!PerItem}"/>
</aura:iteration>
</aura:component>
======================================================================
campingListController.js = campingList.js*controller
({
doInit : function(component, event, helper) {
var action = component.get("c.getItems"); // c of apex controller where getitems takes no arguments
action.setCallback(this, function(response){
var state = response.getState();
if (component.isValid() && state === "SUCCESS") {
// setting the items array at the view page- campingList.cmp
component.set("v.items", response.getReturnValue());
}
else {
console.log("Failed with state: " + state);
}
});
$A.enqueueAction(action);
},
CreateCamping : function(component, event, helper){
//sending fields for validations at the helper function: campingList*Helper.js
helper.validateFields (component,component.find("name"));
helper.validateFields (component,component.find("Price"));
helper.validateFields (component,component.find("Quantity"));
// if any of the firled s failes validation the v.er is being set to true
if(component.get("v.er") === false)
{
// get object and object list
var lstItems = component.get("v.items");
var Item = component.get("v.newItem");
// call to helper function to communicate with the apex controller
helper.createItem(component,Item);
}
}
})
================================================================
campingListHelper.js = campingList.js*helper
({
validateFields : function (component,field) {
var nameField = field;
console.log('yes:'+nameField);
var expname = nameField.get("v.value");
if ($A.util.isEmpty(expname)){
component.set("v.er",true);
nameField.set("v.errors", [{message:"this field can't be blank."}]);
}
else {
nameField.set("v.errors", null);
}
},
createItem: function(component, item) {
console.log("from helper "+item);
// attempt to
// var newItem = item;//component.get("v.newItem");
// console.log("from helper overrriden Item"+newItem);
var action = component.get("c.saveItem"); // function at the apex controller
console.log("action "+action);
action.setParams({"campingItem": newItem}); // the function takes a prameter "campingItem" we insert "newItem" into it
action.setCallback(this, function(response){
var state = response.getState();
if (component.isValid() && state === "SUCCESS") {
var lstItems = component.get("v.items");
var Item = component.get("v.newItem");
// call to helper function to communicate with the apex controller
//UPDATE VIEWER PART ONLY IF THE UPSERT WAS SECCESSFULL
lstItems.push(Item);
component.set("v.items",lstItems);
// trigger update reset newItem fields
component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
'Name': '',
'Quantity__c': 0,
'Price__c': 0,
'Packed__c': false }); }
else
{
console.log("something failed "+state);
}
});
$A.enqueueAction(action);
}
})
===============================================================
campingListItem.cmp
<aura:component >
<aura:attribute type="Camping_Item__c" name="item" required="true"/>
Name:
<lightning:formattedText value="{!v.item.Name}" /><br/>
Packed:
<lightning:input type="toggle" checked="{!v.item.Packed__c}" /><br/>
Price:
<lightning:formattedNumber value="{!v.item.Price__c}" style="currency"/><br/>
Quantity:
<lightning:formattedNumber value="{!v.item.Quantity__c}" /><br/>
<ui:button label="Packed!" press="{!c.packItem}" aura:id="Button"/> <br/>
</aura:component>
========================================================================
harnessApp.app
<aura:application extends="force:slds">
<!-- This component is the real "app" -->
<c:camping />
</aura:application>
=======================================================================
campingListController.apxc
public with sharing class CampingListController {
@AuraEnabled
public static List<Camping_Item__c> getItems() {
// Perform isAccessible() checking first, then
return [SELECT Id, Name, price__c, Quantity__c, Packed__c
FROM Camping_Item__c];
}
@AuraEnabled
public static Camping_Item__c saveItem(Camping_Item__c campingItem) {
// List<Camping_Item__c> newList = getItems();
// system.debug('the new item '+campingItem);
// system.debug('campingItem b4 adding'+newList);
//newList.add(campingItem);
// system.debug('campingItem after adding'+newList);
upsert campingItem;
return campingItem;
}
}
Below code will help in completing the Connect to Salesforce with Server-Side Controllers exercise
CampingList Component
<aura:component controller="CampingListController" >
<aura:attribute name="items" type="Camping_Item__c[]" />
<aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
<aura:attribute name="newItem" type="Camping_Item__c" default="{'sObjectType':'Camping_Item__c','Quantity__c':0,'Price__c':0}" />
<br/><br/>
<p>Name:
<ui:inputText aura:id="name" value="{!v.newItem.Name}" Label="Name" />
</p><br/>
<p>Quantity:
<ui:inputNumber aura:id="quantity" value="{!v.newItem.Quantity__c}" Label="Quantity" />
</p><br/>
<p>Price:
<ui:inputCurrency aura:id="price" value="{!v.newItem.Price__c}" Label="Price" />
</p><br/>
<p>Packed?:
<ui:inputCheckBox value="{!v.newItem.Packed__c}" Label="Packed" />
</p><br />
<ui:button label="Submit" press="{!c.PushItems}" />
<aura:iteration items="{!v.items}" var="item">
<p> <ui:outputText value="{!item.Name}" /> </p>
<p> <ui:outputNumber value="{!item.Quantity__c}" /> </p>
<p> <ui:outputCurrency value="{!item.Price__c}" /> </p>
<p> <ui:outputCheckbox value="{!item.Packed__c}" /> </p>
</aura:iteration>
</aura:component>
CampingList 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"){
console.log('From action variable : '+JSON.parse(JSON.stringify(response.getReturnValue())));
component.set("v.items",JSON.parse(JSON.stringify(response.getReturnValue())));
}
else{
console.log("Failed with State : " + state);
}
});
$A.enqueueAction(action);
},
PushItems : function(component, event, helper) {
var validItem = true;
var nitem = component.get("v.newItem");
var iName = component.find("name");
var iQuantity = component.find("quantity");
var iPrice = component.find("price");
if($A.util.isEmpty(iName.get("v.value"))){
console.log('Checking Name is null');
validItem = false;
iName.set("v.errors",[{message:"Item Name cannot be blank"}]);
}else if($A.util.isEmpty(iQuantity.get("v.value"))){
validItem = false;
iQuantity.set("v.errors",[{message:"Item Quantity cannot be blank"}]);
}else if($A.util.isEmpty(iPrice.get("v.value"))){
validItem = false;
iPrice.set("v.errors",[{message:"Item Price cannot be blank"}]);
}
if(validItem){
var pitem = JSON.parse(JSON.stringify(nitem));
helper.createItem(component,pitem);
}
}
})
CampingList Helper
({
createItem : function(component,strcamp) {
var action = component.get("c.saveItem");
action.setParams({
"strcamp" : strcamp
});
action.setCallback(this,function(response){
var state = response.getState();
console.log('Status of the response is : ' + state);
if(state === "SUCCESS"){
var ilist = component.get("v.items");
ilist.push(strcamp);
component.set("v.items",ilist);
component.set("v.newItem",{'sObjectType':'Camping_Item__c','Name':' ','Quantity__c':0,'Price__c':0});
}
else{
console.log('Errored Out');
}
});
$A.enqueueAction(action);
}
})
CampingListController APEX Class
public class CampingListController{
@AuraEnabled
public static list<Camping_Item__c> getItems(){
System.debug('Method is invoked');
return ([select Name,Packed__c,Price__c,Quantity__c from Camping_Item__c]);
}
@AuraEnabled
public static void saveItem(Camping_Item__c strcamp){
//Camping_Item__c ci = (Camping_Item__c)JSON.deserialize(strcamp,Camping_Item__c.class);
//System.debug('Inserted Camping Item : ' + ci);
insert strcamp;
}
}
I have also an issue with this.
My code works but cannot pass trailhead
campingListHelper.js
```
({
createItem : function(item, action, component) {
var items = component.get("v.items");
action.setParams({
"item" : item
});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
items.push(item);
component.set("v.items", items);
component.set("v.newItem",{ 'sobjectType':
'Camping_Item__c',
'Name': '',
'Quantity__c': 0,
'Price__c': 0,
'Packed__c': false });
}
});
$A.enqueueAction(action);
}
})
```
campingListController.js
```
({
clickCreateItem : function(component, event, helper) {
var validListItem = component.find('itemform').reduce(function(validSoFar, inputCmp){
inputCmp.showHelpMessageIfInvalid();
return validSoFar && inputCmp.get('v.validity').valid;
}, true);
if (validListItem) {
var currentItem = component.get("v.newItem");
var newItem = JSON.parse(JSON.stringify(currentItem));
var action = component.get("c.saveItem");
helper.createItem(newItem, action, component);
}
},
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) {
console.log("callback");
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);
}
})
```
CampingListController.apxc
```
public class CampingListController {
@AuraEnabled
public static List<Camping_Item__c> getItems() {
System.debug('Called get Items');
List<Camping_Item__c> campingItems = [SELECT Name, Price__c, Quantity__c, Packed__c FROM Camping_Item__c];
return campingItems;
}
@AuraEnabled
public static Camping_Item__c saveItem(Camping_Item__c item) {
try{
upsert item;
System.debug('success');
} catch (Exception e) {
System.debug('error found');
}
return item;
}
}
```
my error message is
````
Challenge not yet complete... here's what's wrong:
The campingList JavaScript helper doesn't appear to have the correct functionality. Ensure that it is saving the new record to the database and in the callback, pushing the new record to the array of existing items (e.g., v.items) and setting the modified array of items to the 'items' value provider to display the updated list.
```
thanks for any help!
.