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
Kashona DotsonKashona Dotson 

How to save new values from component to database

Uncaught Error in $A.getCallback() [items.push is not a function]
Callback failed: apex://MassUpdateController/ACTION$saaave

cmp
<lightning:button variant="brand" label="Save" onclick="{!c.saveTable}" />
controller.js
saveTable : function(component, event, helper) {   
        var action = component.get("c.saaave");
        var items = component.get("v.selectedStatus");
        var atd = component.get("v.relatedAttendees");
        action.setParams({"v.selectedStatus": JSON.stringify(items)});
        action.setCallback(this, function(data){
            var state = data.getState();
            if (component.isValid() && state === "SUCCESS") {
                items.push(data.getReturnValue());
                component.set("v.selectedStatus", atd);
            }
        });
        $A.enqueueAction(action);
    },


controller.apxc
@AuraEnabled
        public static void saaave(){
            list<RIM_Item__c> ple = new list<RIM_Item__c>();
            ple = [select id, Decision__c from RIM_Item__c];
            RIM_Item__c itms = new RIM_Item__c();
            itms.id=ple[0].id;
            update itms;
        }




 
Danish HodaDanish Hoda
Hi Kashona,
1. Quick question, what are relatedattendees and selectedStatus attributes and how are they related?
2. Your apex class doesn't require a parameter, you need not use action.setparams().
you can refer below code, per my undersating of your requirement:
saveTable : function(component, event, helper) {   
        var action = component.get("c.saaave");
        //var items = component.get("v.selectedStatus");
		var items = [];
        //var atd = component.get("v.relatedAttendees");
        action.setCallback(this, function(data){
            var state = data.getState();
            if (state === "SUCCESS") {
                items.push(data.getReturnValue());
                //component.set("v.selectedStatus", atd);
				component.set("v.selectedStatus", items);
            }
        });
        $A.enqueueAction(action);
    },


 
Kashona DotsonKashona Dotson
Hi Danish!

First of all, thank you for your response and I appreciate your time very much!

relatedAttendees are a set of related child records (such as Contacts). selectedStatus is a picklist field on those related records, that I am updating from the parent record page (i.e. Account). Here is an image of the component in action: (Decision column = selectedStatus)
User-added image

I am just trying to get the save button to take the new values selected and push them to the existing records and save. And I have no idea what I'm doing :) just fumbling about in the code. I made the changes you specified and I am no longer getting an error, but also the related records are not saving with the new values.
Kashona DotsonKashona Dotson
Additional information: I am creating this list via iteration and not a datatable as that does not support picklist edits
Danish HodaDanish Hoda
Hi Kashona,
Are you having Ids of child records in the component shown?
Kashona DotsonKashona Dotson
EDITED: Here is my full code:  I don't know how to get it to find the new selected options and push them to the children.. It's a bit messy, "Attendee" and "RIM_Item__c" are interchangable and reference the child records. "Decision__c" and "Status" are interchangable and reference the picklist field on the child records that I want to update. "RIM__c" is the parent record where the component is located.

cmp.js
<!--massUpdateAttendeeStatus-->
<aura:component access="global" controller="MassUpdateController" 
                implements="flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,
                            force:hasRecordId,force:hasSObjectName">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="relatedAttendees" type="MassUpdateController.wrapAttendeeRecord[]"/>
    <aura:attribute name="selectedAttendees" type="MassUpdateController.wrapAttendeeRecord[]"/>
    <aura:attribute name="attendeeStatusList" type="String[]"/>
    <aura:attribute name="selectAll" type="boolean" default="false"/>
    <aura:attribute name="selectedStatus" type="String"/>
    <aura:attribute name="RIM__c" type="Object"/>
    <aura:attribute name="RIM_Item__c" type="Object"/>
        <force:recordData aura:id="rRecord"
                  recordId="{!v.recordId}"
                  targetFields="{!v.RIM__c}"
                  layoutType="FULL"
                          mode="EDIT"/>

<lightning:card iconName="custom:custom41" title="{! 'Item List for ' + v.RIM__c.Customer_Name__c}">     

<div class="slds-form slds-p-horizontal_medium" role="list">
<div class="slds-form__row"><div class="slds-form__item" role="listitem">
<div class="slds-form-element slds-form-element_horizontal slds-is-editing">    
      <lightning:select name="selectItem" label="Apply Decision to Selected:" value="{!v.selectedStatus}" onchange="{!c.setStatus}">
               <option text="None" value="{!v.value}"></option>
               <aura:iteration items="{!v.attendeeStatusList}" var="stat">
                     <option text="{!stat}" value="{!stat}"></option>                    
               </aura:iteration>                    
       </lightning:select>
</div></div></div></div>  <!-- BEGIN TABLE JUNK -->
    
    <table class="slds-table">
        <thead>
            <tr class="slds-text-title_caps slds-line-height_reset">
                <th class="" style="width:10px">
                    <ui:inputCheckbox aura:id="box3" value="{!v.selectAll}" change="{!c.onCheck}"/></th>
                <th class="slds-p-around_xxx-small" scope="col"><div class="" title="Type">Type</div></th> 
                <th class="slds-p-around_xxx-small" scope="col"><div class="" title="Transaction Amount">Amount</div></th>               
                <th class="slds-p-around_xxx-small" scope="col"><div class="" title="Decision">Decision</div></th>
            </tr>
        </thead>
        <tbody>
            
<aura:iteration items="{!v.relatedAttendees}" var="atd">
<tr>
	<td><div class="" style="width:10px">
        <ui:inputCheckbox aura:id="boxPack" value="{!atd.attendeeSelected}"/></div>
    </td>
		
	<td data-label="Type">
	<div class="slds-form-element__control" title="Type">
		<p class="slds-text-body_regular">{!atd.wrapAttendee.Transaction_Type__c}</p>
	</div></td>
                    
	<td data-label="Transaction Amount">
	<div class="slds-form-element__control" title="Transaction Amount">
           <p><lightning:formattedNumber value="{!atd.wrapAttendee.Transaction_Amount_Detail__c}" style="currency" currencyCode="USD"/></p>
	</div></td>             
                    
	<td data-label="Decision">
		<ui:inputSelect  class="slds-select spear-select" aura:id="selectItem" value="{!atd.wrapAttendee.Decision__c}" updateOn="change" >    
			<aura:iteration items="{!v.attendeeStatusList}" var="stat">
				<ui:inputSelectOption text="{!stat}" label="{!stat}" value="{!stat==atd.wrapAttendee.Decision__c}" />            
			</aura:iteration>    
		</ui:inputSelect>
<!-- aura:if isTrue="{!atd.wrapAttendee.Status__c == 'Attended'}"><img src="{!$Resource.manageAttendeesImages + '/attended.gif'}"/></aura:if>&nbsp;-->
	</td>               
</tr></aura:iteration></tbody><br/> </table>	<!--BEGIN BUTTONS-->
    
            <div align="center">
                <lightning:button variant="neutral" label="Nvm" onclick="{!c.cancel}" />
                <lightning:button variant="brand" label="GO!" onclick="{!c.changeStatus}" /> 
            </div>

    </lightning:card>
</aura:component>
controller.js
({
    doInit : function(component, event, helper) {
        var action = component.get("c.getAllRelatedAttendees");  
        action.setParams({
            "visitRecordId" : component.get("v.recordId")});
        action.setCallback(this, function(a) {            
            component.set("v.relatedAttendees", a.getReturnValue());});
        $A.enqueueAction(action); 
		helper.getPrepopulatedValues(component, event, helper);},

    onCheck : function(component, event, helper) {
        var selAll = component.get("v.selectAll");
        var newlst =[];    
        var allAttendees = component.get("v.relatedAttendees");
        for(var i in allAttendees){
            var space = allAttendees[i];                    
            space.attendeeSelected = selAll;             
            newlst.push(space);}
        component.set("v.selectedAttendees",newlst);
        component.set("v.relatedAttendees",newlst);},

    setStatus : function(component, event, helper) {
        var selcStatus = component.get("v.selectedStatus");
        var newlst =[];    
        var allAttendees = component.get("v.relatedAttendees");
        for(var i in allAttendees){
            var space = allAttendees[i];                    
            if(space.attendeeSelected === true){
                space.wrapAttendee.Decision__c = selcStatus;}
            newlst.push(space);}
        component.set("v.relatedAttendees",newlst);}, 

    changeStatus : function(component, event, helper) {
        var allAttendees = component.get("v.relatedAttendees");
        for(var i in allAttendees){
            var space = allAttendees[i];    
            //alert("Decision: " + space.wrapAttendee.Decision__c);
        }
        
        
    }, 
    
    cancel : function (component, event, helper) {
        var action = component.get("c.getAllRelatedAttendees");  
        action.setParams({
            "visitRecordId" : component.get("v.recordId")});
        action.setCallback(this, function(a) {            
            component.set("v.relatedAttendees", a.getReturnValue());});
        $A.enqueueAction(action); 
		helper.getPrepopulatedValues(component, event, helper);
    },
})
controller.apxc
public class MassUpdateController {
    @auraEnabled
    public static List<wrapAttendeeRecord> getAllRelatedAttendees(Id visitRecordId){
        List<wrapAttendeeRecord> wrapAttendeeRecordList = new List<wrapAttendeeRecord>();
        for(RIM_Item__c atd : [select Id, Name, RIM__r.Name, Decision__c, Transaction_Amount_Detail__c, 
                               Transaction_Type__c, RIM__r.Customer_Name__c 
                               from RIM_Item__c where RIM__c = :visitRecordId]){
            wrapAttendeeRecordList.add(new wrapAttendeeRecord(atd));
        }
        return wrapAttendeeRecordList;
    }
    @auraEnabled
    public static List<String> getStatusValues(){
        List<String> options = new List<String>();
        Schema.DescribeFieldResult fieldResult = RIM_Item__c.Decision__c.getDescribe();
        List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
        for (Schema.PicklistEntry f: ple) {
            options.add(f.getLabel());
        }
        return options;
    }
    //==================================================================
    @auraEnabled
    public static RIM_Item__c saveDcn(RIM_Item__c dcns){
        UPDATE dcns;
        RETURN dcns;
    }
    //==================================================================

    public class wrapAttendeeRecord{
        @auraEnabled
        public boolean attendeeSelected{get; set;}

        @auraEnabled
        public RIM_Item__c wrapAttendee{get; set;}

        @auraEnabled
        public boolean isAttended{get; set;}

        public wrapAttendeeRecord(RIM_Item__c atd){
            attendeeSelected = false;
            wrapAttendee = atd;
            if(atd.Decision__c == 'Pay and Waive'){
                isAttended = true;
            }else{
                isAttended = false;
            }
        }
    }
}
helper.js
({
    getPrepopulatedValues : function(component, event, helper) {
        var action = component.get("c.getStatusValues");
        action.setCallback(this, function(a) {            
            component.set("v.attendeeStatusList", a.getReturnValue());
        });
        $A.enqueueAction(action);
    },
})