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
krios demokrios demo 

how to pass the array of object from JS to Apex

I have iterated the OpportunityLineItem in HTML with property ProductData and displayed the OPP LineItem in tabular format.
I have to edit the OppLineItem and wanted to save in apex below is my Apex , HTML, and JS code for the same. Please correct the code.

HTML:

<template if:true={EditButton}>
    <template for:each={ProductData} for:item="row">
        <tr key={row.Id}>
            <td style="text-align: center; padding: 6px; border: 1px solid;">{row.Product2.Description}</td>
            <td style="text-align: center; padding: 6px; border: 1px solid;">{row.Quantity}</td>
            <td style="text-align: center; padding: 6px; border: 1px solid;">{row.UnitPrice}</td>
            <td style="text-align: center; padding: 6px; border: 1px solid;">{row.TotalPrice}</td>
            <td class="slds-p-around_xx-small" style="align: center; padding: 6px; border: 1px solid;"> 
                <lightning-input type='text' name='Colour' data-id={row.Id} value={Colour} disabled={disabled} data-field-modified>
                </lightning-input></td>
            <td class="slds-p-around_xx-small" style="align: center; padding: 6px; border: 1px solid;"> 
                <lightning-input type='text' name='Customization' data-id={row.Id} value={Customization} disabled={disabled} data-field-modified></lightning-input></td>
            <td class="slds-p-around_xx-small" style="text-align: center; padding: 6px; border: 1px solid;">
                <lightning-input type='text' name='Packing' data-id={row.Id} value={Packing} disabled={disabled} data-field-modified></lightning-input></td>
            <td class="slds-p-around_xx-small" style="text-align: center; padding: 6px; border: 1px solid;"> 
                                <lightning-combobox label="" name="NewCode" variant="label-stacked" placeholder="Select Option" class="priorityAlign" value={New_Code_Required} data-id={row.Id} options={NewCodeOptions} disabled={disabled} data-field-modified></lightning-combobox></td>
        </tr>
    </template>
</template>

JS:

handleSave(){
        this.sendmail = false;

        const modifiedRecords = [];
        const inputFields = this.template.querySelectorAll('[data-field-modified]');

        inputFields.forEach((input) => {
            const rowId = input.dataset.id;
            const fieldName = input.name;
            const modifiedValue = input.value;
            modifiedRecords.push({ rowId, fieldName, modifiedValue });
        });

        console.log("Modified Records: ", modifiedRecords);
        
        SaveRecord({ modifiedRecords })
        .then(result => {
            console.log('Data Saved Successfully...');
            this.data = result;
            console.log('DATA ::', this.data);

            const evt = new ShowToastEvent({
                title: 'Save Data',
                message: 'Save sucessfully',
                variant: 'success',
                mode: 'dismissable'
            });

            this.dispatchEvent(evt);
            console.log("Event Dispatched and OLI Saved Successfully...!");

        })
        .catch(error => {
            console.log('Inside Save Action error');
            this.error = error;
            console.log('Error ::', this.error);
        })
    }

Apex:

@AuraEnabled
    public static void SaveRecord(List<ModifiedRecord> modifiedRecords) {
        System.debug('modified records=====>'+modifiedRecords);
        
          List<OpportunityLineItem> oppLineItemsToUpdate = new List<OpportunityLineItem>();

          for (ModifiedRecord record : modifiedRecords) {
            OpportunityLineItem oli = [SELECT Id,Product2.Description, Quantity, UnitPrice, TotalPrice, Colour__c, Customization__c, Packing__c, New_Code_Required__c FROM OpportunityLineItem WHERE Id =: record.rowId];
            
            if (oli != null) {
                  if (record.fieldName == 'Colour') {
                    oli.Colour__c = record.modifiedValue;
                    System.debug('Colour:'+oli.Colour__c);
                  } else if (record.fieldName == 'Customization') {
                    oli.Customization__c = record.modifiedValue;
                    System.debug('Customization:'+oli.Customization__c);
                  } else if (record.fieldName == 'Packing') {
                    oli.Packing__c = record.modifiedValue;
                    System.debug('Packing:'+oli.Packing__c);
                  } else if (record.fieldName == 'NewCode') {
                    oli.New_Code_Required__c = record.modifiedValue;
                    System.debug('New_Code_Required:'+oli.New_Code_Required__c);
              }
                oppLineItemsToUpdate.add(oli);
                System.debug('oppLineItemsToUpdate'+oppLineItemsToUpdate);
            }
        }
        if (!oppLineItemsToUpdate.isEmpty()) {
        update oppLineItemsToUpdate;
    }
        System.debug('oppLineItemsToUpdate'+oppLineItemsToUpdate);
        
    }
    
    public class ModifiedRecord {
          @AuraEnabled
          public String rowId { get; set;}
        
          @AuraEnabled
          public String fieldName { get; set;}  
        
          @AuraEnabled
          public String modifiedValue { get; set;}    
        
    }

Provide the solution asap.....
Best Answer chosen by krios demo
SubratSubrat (Salesforce Developers) 
Hello Krios ,

Based on the code you provided, it seems that you're attempting to pass an array of modified records from your JavaScript code to the Apex controller. However, there are a few corrections needed in your code to ensure it functions correctly. Here are the necessary adjustments:

HTML:
In your HTML code, make sure to bind the attribute values in the lightning-input and lightning-combobox components to the respective properties of the row object. Update the bindings as follows:
<lightning-input type='text' name='Colour' data-id={row.Id} value={row.Colour__c} disabled={disabled} data-field-modified>
</lightning-input>

<lightning-input type='text' name='Customization' data-id={row.Id} value={row.Customization__c} disabled={disabled} data-field-modified></lightning-input>

<lightning-input type='text' name='Packing' data-id={row.Id} value={row.Packing__c} disabled={disabled} data-field-modified></lightning-input>

<lightning-combobox label="" name="NewCode" variant="label-stacked" placeholder="Select Option" class="priorityAlign" value={row.New_Code_Required__c} data-id={row.Id} options={NewCodeOptions} disabled={disabled} data-field-modified></lightning-combobox>

JS:
In your JavaScript code, modify the handleSave() function as follows:
handleSave() {
    this.sendmail = false;

    const modifiedRecords = [];

    this.ProductData.forEach((row) => {
        const modifiedRecord = {
            rowId: row.Id,
            fieldName: '',
            modifiedValue: ''
        };

        if (row.Colour__c !== row.Colour) {
            modifiedRecord.fieldName = 'Colour';
            modifiedRecord.modifiedValue = row.Colour__c;
            modifiedRecords.push(modifiedRecord);
        }

        if (row.Customization__c !== row.Customization) {
            modifiedRecord.fieldName = 'Customization';
            modifiedRecord.modifiedValue = row.Customization__c;
            modifiedRecords.push(modifiedRecord);
        }

        if (row.Packing__c !== row.Packing) {
            modifiedRecord.fieldName = 'Packing';
            modifiedRecord.modifiedValue = row.Packing__c;
            modifiedRecords.push(modifiedRecord);
        }

        if (row.New_Code_Required__c !== row.NewCode) {
            modifiedRecord.fieldName = 'NewCode';
            modifiedRecord.modifiedValue = row.New_Code_Required__c;
            modifiedRecords.push(modifiedRecord);
        }
    });

    console.log('Modified Records: ', modifiedRecords);

    SaveRecord({ modifiedRecords })
        .then(result => {
            console.log('Data Saved Successfully...');
            this.data = result;
            console.log('DATA ::', this.data);

            const evt = new ShowToastEvent({
                title: 'Save Data',
                message: 'Save successfully',
                variant: 'success',
                mode: 'dismissable'
            });

            this.dispatchEvent(evt);
            console.log('Event Dispatched and OLI Saved Successfully...!');
        })
        .catch(error => {
            console.log('Inside Save Action error');
            this.error = error;
            console.log('Error ::', this.error);
        });
}

Hope this helps !
Thank you.​​​​​​​