[SalesForce] LWC data table JS issue: “cannot add property accountName, object is not extensible”

APEX CLASS

 public with sharing class datatabletest{
    @AuraEnabled(cacheable=true)
    public static List<Theme__c> getData(string userId) {
        return [SELECT Account__r.name, Account__c, Name, Risk_Level__c 
                FROM Theme__c 
                WHERE (Risk_Level__c != null AND Risk_Action__c = null)
                AND Account__r.OwnerId =: userId];
    }
  }

snippet of JS: you can see where my main issue it.

// retrieving the data using wire service
    @wire(getData, {userId: '$UserId'})
    themeData(result) {



         // get the account name
        if (result.data) { 


            let dataParse;
            let datas = result.data;
            for (let i = 0; i < datas.length; i++) {
                 dataParse = datas[i];
                if (dataParse.Account__r) dataParse.accountName = dataParse.Account__r.Name;

            }
            this.data = dataParse;

Html of the table, just if someone asks

          <template if:true={data}>

           <lightning-datatable data={data}
                                columns={columns}
                                key-field="id"
                                hide-checkbox-column="true"
                                onrowaction={handleRowActions}></lightning-datatable>
       </template>

   </div>

Now the reason i'm querying both the Id of the account and the account__r.name is because in my columns section where i define the columns i'm going to create a link to the record id but give it the label of the actual name….

also on an action i need the Id values because i'm going to use a lightning-record-edit-form to create a related object record and i pass the id values from the row…now all of that works but i just can't get the damn name of the account to display on the data table.

For those curious my edit form is at the bottom of this post.

unrelated: Also i noticed something weird.

    {
"Account__c":"0013000000bBCerAAG",
"Name":"Hard Wood",
"Risk_Level__c":"Medium",
"Id":"a4VQ0000000niplMAA",
    "Account__r":
    {
"Name":"Table Mountain",
"Id":"0013000000bBCerAAG"
    }
},

Even though i don't query the Theme__c Id it gives it to me anyways. Also when i query Account__r.Name it returns a Id value do i even need to query the Account__c field directly for the Id value?? It's just so frustrating, there has to be some easier way of accessing those account__r values when creating the columns of the data table.


Here's the edit form for those curious, value= {vars i defined in js} it automatically passes the id values to those lookup fields. if the edit form doesn't have a recordId defined then it just a create new based on the object in object-api-name

           <div if:true={isEditForm} class="slds-theme_default">
           <lightning-record-edit-form layout-type="Full"  object-api-name="Theme_Action__c" onsubmit={handleSubmit} onsuccess={handleSuccess}>
               <lightning-messages></lightning-messages>

               <lightning-input-field field-name="Account__c" value={Account_Id} ></lightning-input-field>
               <lightning-input-field field-name="heme__c" value={themeId}></lightning-input-field>
               <lightning-input-field field-name="Action__c"></lightning-input-field>
               <br/>

               <div style="text-align:center;">
                   <lightning-button class="slds-m-top_small"
                                     variant="brand"
                                     type="submit"
                                     name="update"
                                     label="Create Record"></lightning-button>
               </div>
           </lightning-record-edit-form><br/>
           <div></div>
       </div>

EDIT:

i changed up my JS

         // flatten out data
    if (result.data){ 
        console.log(' this data' + JSON.stringify(result.data));    

        let dataParse;
        for (let i = 0; i <  result.data.length; i++) {             
            dataParse = Object.assign({},  result.data[i]);
            if (dataParse.Account__r) dataParse.accountName = dataParse.Account__r.Name;


        }

        this.data = dataParse;

Now when i console log dataParse outside of the loop i get this

 {"Account__c":"0013000000bBCerAAG","Name":"WOF Pink Diamond 3R1L2C $5","Risk_Level__c":"High","Id":"a4VQ0000000nmqmMAA","Account__r":
{"Name":"hard wood","Id":"0013000000bBCerAAG"},"accountName":"Table Mountain Casino"}

and that's it. just one record.

when console.log the initial result.data

    [{"Account__c":"0013000000bBCerAAG","Name":"FORTUNE GONG with DRAGON  ASC CURVE","Risk_Level__c":"Medium","Id":"a4VQ0000000niplMAA",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"WOF CL EXOTIC FAR EAST ASC","Risk_Level__c":"Medium","Id":"a4VQ0000000njLyMAI",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"CD+ ASC - JIN LONG 888 3R","Risk_Level__c":"High","Id":"a4VQ0000000njhqMAA",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"REEF OF RICHES 3D","Risk_Level__c":"High","Id":"a4VQ0000000njsrMAA",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"TEMPLE OF TREASURE TPL GOLD ASC","Risk_Level__c":"Medium","Id":"a4VQ0000000nkMjMAI",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"ZUMA 3D","Risk_Level__c":"Medium","Id":"a4VQ0000000nkRGMAY",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"ANYTHING BUT SIX 3D STPR : AXXIS_3D","Risk_Level__c":"Medium","Id":"a4VQ0000000nkxzMAA",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}},
{"Account__c":"0013000000bBCerAAG","Name":"WOF Pink Diamond 3R1L2C $5","Risk_Level__c":"High","Id":"a4VQ0000000nmqmMAA",
"Account__r":{"Name":"hard wood","Id":"0013000000bBCerAAG"}}]

I think it has to do with the account name being the same

Best Answer

Even though i don't query the Theme__c Id it gives it to me anyways.

This happens by default. Queries return ID automatically.

Now when i console log dataParse outside of the loop i get this

Because that's the code you wrote. You're replacing the contents of dataParse each iteration of the loop, so by the end, you only have the last element.

Instead, you will want to copy the array, then each element:

this.data = [...result.data].map(record => ({...record})).forEach(record => record.accountName = record.Account__r.Name);

This will avoid errors regarding elements not being writeable/exensible.

Related Topic