0

I'm new here and have asked 2 questions before and did not get any replies .. not sure if my profile is not visible publically. Even if you are NOT able to answer the question I appreciate if you are able to post a reply saying you can see my question. Thanks

My question - I have a datatable that shows some assignments of tasks on Home page it shows tasks assigned across all objects and on the specific record it shows tasks assigned for that record. The issue is I need to show the Name on Home Page so they can click and go to the record (no comments column) and on record page the assignments are shown in a separate tab and here I don't need to show the Name column but need the comments column. It works fine on initial load of home page or record page or if the pages are refreshed but the issue is if the user navigates say from record1 and then goes to record2 (no refresh) then an additional column is removed and everytime the user navigates between records a column is removed. Using console.log I can see that connectedCallback method is executed between navigation but the strange thing is the this.initialize = false everytime a new record is navigated to but the this.datatableColumns has one less column that was spliced for the previous record. I am NOT an expert and would like to understand what is going and the sequence of execution like when exactly the Const Columns before export default class definition is executed and the variables of class and then ConnectedCallback() .. Please advice.

   <template if:true={isRecordPage}> // seen on RecordPage
     <lightning-datatable
       data={data}
       columns={columnsDataTable}
       key-field="Id"
       is-loading={loading}
     </lightning-datatable>
    </template>
    <template if:false={isRecordPage}>  //seen on Home Page
     <lightning-datatable
       data={data}
       columns={columnsDataTable}
       key-field="Id"
       is-loading={loading}
     </lightning-datatable>
    </template>
    const columns = [
       {
        label: "Name", fieldName: "obj", type: "url",
        typeAttributes: {
           label: {fieldName: "objName"},
           target: "_blank",
           },
        },
        { label: "Date", fieldName: "FieldDate", Type: 'date',
          tyepAttributes: {
              day: 'numeric', month: 'short', year: 'numeric'
              },
        },
        { label: "Status", fieldName: "Status", type: "text" },
        { label: "Assigned", fieldName: "Assigned" , type: "text"},
        { label: "Alternate", fieldName: "Alternate", type: "text"},
        { label: "Comments", fieldName: "Comments", type: "text"}
   ];

   export default class GetAssigned extends LightningElement {

     initialize = false;
     @track data = [];
     loading = false;
    
     @track datatableColumns = columns;
     @api recordId;

     connectedCallback() {
     if(!this.initialize) {
        this.showButton = true;
        if(this.recordId == null) {
           this.isRecordPage = false;
           this.datatableColumns.splice(5,1); // on HomePage datatable does NOT show Comments)
        }
        if(!(this.recordId == null)) {
           this.isRecordPage = true;
           this.datatableColumns.splice(0,1); // on RecordPage (Assignment Tab next to Details) datatable does NOT show Name field
        }
        this.getAssignment();
        this.initialize = true;
      }
    }
    ``` 
     

1 Answer 1

2
  1. When you assign an array to a property or variable, it is passed by reference (kind of- the value of an Array/Object/Function is a reference, and that reference is passed as the value, but you can think of it as passed by reference). When you modify that assigned property or variable, you are modifying the originally declared array. In your case, the const columns is getting modified when you run splice() on this.datatableColumns. While primitive const values can't be modified, arrays and objects can be mutated.

Below is a simplified example of this happening. See how applying the splice to myNewConst actually modifies the original myConst value?

const myConst = ["1", "2", "3"];
let myNewConst = myConst;

console.log(myConst); // ["1", "2", "3"]
console.log(myNewConst); // ["1", "2", "3"]

myNewConst.splice(0,1);

console.log(myConst); // ["2", "3"]
console.log(myNewConst); // ["2", "3"]
  1. The second part of what you're seeing is because the const columns is declared outside of the class declaration, and is therefore shared among all instances of your component, meaning when you mutate that const, you are mutating it for every instance of this component until the lightning app is reloaded entirely with a forced refresh.

  2. initialize is false for each call of connectedCallback() because it is defined within that class and each instance of the component will have its own initialize property to work with.

The easiest way to fix this is to change from assigning the reference to assigning a copy of the array. Pretty easy with the spread notation:

const myConst = ["1", "2", "3"];
let myNewConst = [...myConst];

console.log(myConst); // ["1", "2", "3"]
console.log(myNewConst); // ["1", "2", "3"]

myNewConst.splice(0,1);

console.log(myConst); // ["1", "2", "3"]
console.log(myNewConst); // ["2", "3"]

Although you may want to think about other approaches that may be more expressive about what you're doing. Are there other use cases that you anticipate this will need to support? If someone else (or future you) were to come and look at this code, how easy will it be for them to reason about what is happening, why, and where to make changes/enhancements? Just my two cents. Happy coding!

2
  • Great explanation and thanks a lot. The columns they want to show may change but I will look into other scenarios just to be sure and will add comments for future developers. I appreciate much. Happy Holidays!
    – techfordev
    Dec 20, 2021 at 18:06
  • linked this answer on developer.salesforce.com as I had asked the question there as well. Hope its ok.
    – techfordev
    Dec 20, 2021 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.