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
Alexander AtkinsonAlexander Atkinson 

Lightning Component: Create array of accounts in JavaScript with new fields based on component values. Then send to apex for database update

Hi, I'm having understanding how to update my database of accounts with new field values based on component item variables.
Below are the fields, and the values they need to be set to.
  • name = item.title
  • id = item.id
  • table_number__c = item.status

JavaScript Controller: 
updateAccounts: function(component, event, helper) 
    {
        var action = component.get("c.updateAccounts");
        var itemsToPass = component.get("v.allItems"); //Items in the component
        var AccountsToUpdate = []; //Items that will be sent to 
        
        //Go through items in the component.
        //Create a list of accounts. Account name = itemname, Account id = item id, Table Name = Status
        for (var i=0; i< itemsToPass.length; i++)
        {
            var item = itemsToPass[i];
            var Account = {Name: item.title, Id: item.Id, Table_Name__c: item.status};

            //Push each account to the array.
            AccountsToUpdate.push(Account);
        } 
        //Pass the array into Apex list.
        action.setParams({ "changes": AccountsToUpdate  });
        $A.enqueueAction(action); 
    }
Apex Controller:
public with sharing class AccountController 
{
    @AuraEnabled
    public static List<Account> getAccounts() 
    {
        List<Account> Accounts =  [SELECT Id, Name, TableName__c FROM Account];
        return Accounts;
    }
    
	@AuraEnabled
    public static List<Account> updateAccounts (List<Account> changes)
    {
        update changes;
        return changes;
    }
}
Component:
<aura:component>	
	<aura:attribute name="allItems" type="list"></aura:attribute>

    <lightning:button label="Save Plan" iconName="utility:save" onclick="{!c.updateAccounts}"/>
</aura:component>


 
Best Answer chosen by Alexander Atkinson
Khan AnasKhan Anas (Salesforce Developers) 
Hi Alexander,

Greetings to you. It is a pleasure to be in touch with you again.

Please try below code:
 
updateAccounts : function(component, event, helper){
        var itemsToPass = component.get("v.allItems"); 
        console.log('itemsToPass -> ' + JSON.stringify(itemsToPass));
        var AccountsToUpdate = [];  

        for (var i=0; i< itemsToPass.length; i++)
        {
            var item = itemsToPass[i];
            var acc = {Name: item.title, Id: item.Id, Table_Name__c: item.status};

            //Push each account to the array.
            AccountsToUpdate.push(acc);
            
        } 
        console.log('AccountsToUpdate -> ' + JSON.stringify(AccountsToUpdate));
        
        var action = component.get("c.updateAccounts");
        action.setParams({changes : AccountsToUpdate});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.allItems", response.getReturnValue());
                alert('Updated Successfully...');
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                    errors[0].message);
                    }
                } 
                else {
                    console.log("Unknown Error");
                }
            }
        });
        $A.enqueueAction(action);
    }

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas

All Answers

Khan AnasKhan Anas (Salesforce Developers) 
Hi Alexander,

Greetings to you. It is a pleasure to be in touch with you again.

Please try below code:
 
updateAccounts : function(component, event, helper){
        var itemsToPass = component.get("v.allItems"); 
        console.log('itemsToPass -> ' + JSON.stringify(itemsToPass));
        var AccountsToUpdate = [];  

        for (var i=0; i< itemsToPass.length; i++)
        {
            var item = itemsToPass[i];
            var acc = {Name: item.title, Id: item.Id, Table_Name__c: item.status};

            //Push each account to the array.
            AccountsToUpdate.push(acc);
            
        } 
        console.log('AccountsToUpdate -> ' + JSON.stringify(AccountsToUpdate));
        
        var action = component.get("c.updateAccounts");
        action.setParams({changes : AccountsToUpdate});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.allItems", response.getReturnValue());
                alert('Updated Successfully...');
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                    errors[0].message);
                    }
                } 
                else {
                    console.log("Unknown Error");
                }
            }
        });
        $A.enqueueAction(action);
    }

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas
This was selected as the best answer
Alexander AtkinsonAlexander Atkinson
Hi, the changes aren't saving despite it giving the alert "Updated successfully...".
The console log outputs ItemsToPass and AccountsToUpdate twice and then "ItemsToPass is undefined" at the end.
Khan AnasKhan Anas (Salesforce Developers) 
Alexander,

Are you using a doInit method in JavaScript controller which you was using previously? Please share complete code along with component.

Regards,
Khan Anas
Khan AnasKhan Anas (Salesforce Developers) 
Alexander,

You are using the same JavaScript method name as the Apex controller method (I forgot to change that). According to this post (https://salesforce.stackexchange.com/questions/129261/enqueued-action-not-executed-in-lightning-component), "A javascript method name in a component controller can never be the same name in an apex lightning controller".
Just need to change the name of your javascript method to be different from the apex method.


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas
Alexander AtkinsonAlexander Atkinson
I have changed the Javascript method to saveChanges and updated the button in the component.
I now have one more error. "Error message: Unable to read SObject".

Do you know the cause of this? Thanks alot for all your help!
Alexander AtkinsonAlexander Atkinson
Hi, another question. I am attempting to serialize the array, then deserialize it into Apex like in https://salesforce.stackexchange.com/questions/172720/lightning-component-unable-to-read-sobject.

I can't seem to figure out how to correctly deserialize my array. 

Apex Class
 
@AuraEnabled
    public static List<Account> updateAccounts (List<Account> changes)
    {
        List<Account> updates = JSON.deserialize(changes, AccountController.class);
        update updates;
        return updates;
    }



Error: Method does not exist or incorrect signature: void deserialize(List<Account>, System.Type) from the type System.JSON
Alexander AtkinsonAlexander Atkinson
Fixed it, there was a typo on "Item.Id". Needed changing to "Item.id".

Thanks for the help!