1

I Have created a LWC to dynamically add rows and insert the records, but the insert is failing with the error below

message :"null input to JSON parser"
stackTrace: "(System Code)\nClass.RingInsert_Handler.insertRings: line 5, column 1"

This works if I use a standard object, but not with my custom Ring Object. Below are my components

JS

import {LightningElement, track} from 'lwc';
import insertRings from '@salesforce/apex/RingInsert_Handler.insertRings'
import {ShowToastEvent} from "lightning/platformShowToastEvent";

export default class LwcDynamicRecordRowsCreation extends LightningElement {

    @track listOfRings;

    connectedCallback() {
        this.initData();
    }

    initData() {
        let listOfRings = [];
        this.createRow(listOfRings);
        this.listOfRings = listOfRings;
    }

    createRow(listOfRings) {
        let ringObject = {};
        if(listOfRings.length > 0) {
            ringObject.index = listOfRings[listOfRings.length - 1].index + 1;
        } else {
            ringObject.index = 1;
        }
        ringObject.Name = null;
        ringObject.Ring_Town__c = null;
        ringObject.Ring_Objective__c = null;
        listOfRings.push(ringObject);
    }

    /**
     * Adds a new row
     */
    addNewRow() {
        this.createRow(this.listOfRings);
    }

    /**
     * Removes the selected row
     */
    removeRow(event) {
        let toBeDeletedRowIndex = event.target.name;

        let listOfRings = [];
        for(let i = 0; i < this.listOfRings.length; i++) {
            let tempRecord = Object.assign({}, this.listOfRings[i]); //cloning object
            if(tempRecord.index !== toBeDeletedRowIndex) {
                listOfRings.push(tempRecord);
            }
        }

        for(let i = 0; i < listOfRings.length; i++) {
            listOfRings[i].index = i + 1;
        }

        this.listOfRings = listOfRings;
    }

    /**
     * Removes all rows
     */
    removeAllRows() {
        let listOfRings = [];
        this.createRow(listOfRings);
        this.listOfRings = listOfRings;
    }

    handleInputChange(event) {
        let index = event.target.dataset.id;
        let fieldName = event.target.name;
        let value = event.target.value;

        for(let i = 0; i < this.listOfRings.length; i++) {
            if(this.listOfRings[i].index === parseInt(index)) {
                this.listOfRings[i][fieldName] = value;
            }
        }
    }

    createRings() {
        insertRings({
            jsonOflistOfRings: JSON.stringify(this.listOfRings)
        })
            .then(data => {
                this.initData();
                let event = new ShowToastEvent({
                    message: "Rings successfully created!",
                    variant: "success",
                    duration: 2000
                });
                this.dispatchEvent(event);
            })
            .catch(error => {
                console.log(error);
            });
    }

}

HTML

<template>

    <div class="slds-card" style="font-family: 'Open Sans', sans-serif">

        <!-- Header -->
        <header class="slds-card__header slds-media slds-media_center">
            <div class="slds-media__figure">
                <lightning-icon icon-name="standard:account" size="small"></lightning-icon>
            </div>
            <div class="slds-media__body slds-card__header-title slds-text-title_bold" style="font-size: 14px">
                Ring Creation
            </div>
        </header>

        <!-- Table -->
        <table class="slds-table slds-table_bordered slds-no-row-hover slds-table_cell-buffer" role="grid">
            <thead>
            <tr>
                <th scope="col" height="22">Name</th>
                <th scope="col" height="22">Objective</th>
                <th scope="col" height="22">Town</th> 
                <th scope="col" height="22" style="width: 3rem"></th>
            </tr>
            </thead>
            <tbody>
            <template for:each={listOfRings} for:item="rec">
                <tr key={rec} class="slds-hint-parent">
                    <td>
                        <lightning-input type="text" variant="label-hidden" label="" data-id={rec.index} name="Name" value={rec.Name} onchange={handleInputChange}></lightning-input>
                    </td>
                    <td>
                        <lightning-input type="text" variant="label-hidden" label="" data-id={rec.index} name="Ring_Town__c" value={rec.Ring_Town__c} onchange={handleInputChange}></lightning-input>
                    </td>
                    <td>
                        <lightning-input type="text" variant="label-hidden" label="" data-id={rec.index} name="Ring_Objective__c" value={rec.Ring_Objective__c} onchange={handleInputChange}></lightning-input>
                    </td>
                    <td>
                        <lightning-button-icon icon-name="utility:delete" alternative-text="Remove" title="Remove" name={rec.index} onclick={removeRow}></lightning-button-icon>
                    </td>
                </tr>
            </template>
            </tbody>
        </table>
        <div class="slds-p-left_small slds-p-vertical_small">
            <lightning-button class="slds-p-right_small" variant="destructive" label="delete all rows" title="delete all rows" icon-name="utility:recycle_bin_full" onclick={removeAllRows}></lightning-button>
            <lightning-button variant="neutral" label="add additional row" title="add additional row" icon-name="utility:add" onclick={addNewRow}></lightning-button>
        </div>

        <!-- Footer -->
        <footer class="slds-modal__footer" style="padding: 0.50rem 1rem;">
            <lightning-button icon-name="utility:save" variant="brand" label="Create Rings" title="Create Rings" onclick={createRings}></lightning-button>
        </footer>
    </div>

</template>

CLS

public without sharing class RingInsert_Handler {

    @AuraEnabled
    public static void insertRings(String jsonOfListOfRings) {
        List<Ring__c> listOfRings = (List<Ring__c>) JSON.deserialize(jsonOfListOfRings, List<Ring__c>.class);
        insert listOfRings;
    }

}

1 Answer 1

1

Due to how JavaScript interacts with the server, the parameters are case sensitive.

Apex: jsonOfListOfRings

JavaScript: jsonOflistOfRings

The L is not capitalized, so it's not received in the Apex code.


Side note: you can avoid the serialization entirely. Just pass in an appropriate object.

@AuraEnabled
public static void insertRings(Ring__c[] rings) {
    insert rings;
}

let ringObject = { sobjectType: 'Ring__c' };

...

createRings() {
    const { rings } = this;
    insertRings({
        rings
    })
    // ... etc
1
  • Thanks! Once again you have provided a very simple solution along with details. I really appreciate your effort! Commented Oct 17, 2022 at 4:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.