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
Kent LichtyKent Lichty 

How to reference an array index or list element as a field name in LWC datatable

I am quite new to LWC programming, and I am being asked to develop an application which I think is relatively "advanced", and I am seeking some help about how to achieve it. The program is using a datatable which I have used many times, but the complexity here is that COLUMNS in the table are dynamic, as well as the property names within those columns.  The basic question is how can I define the property names in javascript when they really don't exist as actual "properties", but simply as list elements?

The screen shot below (I know it's small) will give you an idea of the goal:  I want to list products and for each product, display whether selected price books are active or inactive for that product.  If the price book is active, then a checkbox (with a checkmark) will be displayed, and this is what is NOT happening.  The user will select WHICH price books they wish to see displayed by using the dual-list box at the top.  This is what causes the columns to be dynamic, as well as the property names which appear underneath them.  To keep it simple, I have selected only TWO price books, while in reality many more could be selected.

Screen shot of Application
 
Everything is working fine except that the check marks are not being displayed, and I know they CAN be displayed as I first developed this application using hard-coded columns and property names.  

Here is the stringified JSON that shows the column information, which was built up in Apex, and it looks like I expect it to look.  And you can see from the screen shot that the column headings are working fine.

column list = [{"editable":false,"fieldName":"productLine","label":"Line","type":"text"},{"editable":false,"fieldName":"productSubLine","label":"Sub-Line","type":"text"},{"editable":false,"fieldName":"productName","label":"Product","type":"text"},{"editable":false,"fieldName":"productDescription","label":"Description","type":"text"},{"editable":true,"fieldName":"ActiveStatus[0]","label":"FAO - Fire Alarm Price Book","type":"boolean"},{"editable":true,"fieldName":"ActiveStatus[1]","label":"FSO - Fire Suppression Price Book","type":"boolean"}]

I assume that the problem is with how I defined the fieldName value, because that field name is not a true "property" in a class, but a list element from a list in my wrapper class that is a property.   So the only way I know how to define it is as an array element which you see from the above is "ActiveStatus[0]" and "ActiveStatus[1]".  My guess is that this syntax is simply wrong, but I don't know how else to define this field name dynamically.

Here is the actual value of my list (after JSON.stringify) and it looks correct to me. You can see that both elements of the "ActiveStatus" list are set to "true".

list = [{"ActiveStatus":[true,true],"productDescription":"SPLICING TAPE,BLUE PROTECTOWIRE","productId":"01t21000004jHdeAAE","productLine":"Linear Heat","productName":"#35 BLUE","productSubLine":"Accessories-Linear Heat"},{"ActiveStatus":[true,true],"productDescription":"SPLICING TAPE,RED PROTECTOWIRE","productId":"01t21000004jHdsAAE","productLine":"Linear Heat","productName":"#35 RED","productSubLine":"Accessories-Linear Heat"},{"ActiveStatus":[true,true],"productDescription":"SPLICING TAPE,WHITE PROTECTOWIRE","productId":"01t21000004jHcrAAE","productLine":"Linear Heat","productName":"#35 WHITE","productSubLine":"Accessories-Linear Heat"}]

That is really my basic question: how do I define my field names when they are not hard-coded properties in my wrapper class?  I know that I can take a lame way out and define a bunch of property values in my wrapper class (isActive001, isActive002, ...... isActive100) but this approach is not optimal and I think it can done using the dynamic alternative, if I could figure it out.

I don't think it's really relevant, but here are some more code fragments which are perhaps applicable:

This is my Apex wrapper class defines the datatable row:

public class FikeAltPbWrapper2
{
    @AuraEnabled
    public Id productId {get;set;}
    
   @AuraEnabled
    public String productName {get;set;}
    
    @AuraEnabled
   public String productLine {get;set;}
    
    @AuraEnabled
    public String productSubLine {get;set;}
    
   @AuraEnabled
    public String productDescription {get;set;}

    @AuraEnabled
    public List <boolean> ActiveStatus {get;set;}
        
    public FikeAltPbWrapper2 (Id productId, String productName, String productLine, String                       productSubLine,   String productDescription, List <boolean>                      ActiveStatus )  
    {
        this.productId = productId;
        this.productName = productName;
        this.productLine = productLine;
        this.productSubLine = productSubLine;
        this.productDescription = productDescription;
        this.ActiveStatus = ActiveStatus;
    }

} //End of Class


And here is the javascript function:
@wire(getWrapperList, {productCategorySearchKey: '$productCategorySearchKey', 
                          productFamilySearchKey: '$productFamilySearchKey',
                          productLineSearchKey: '$productLineSearchKey',
                          productSubLineSearchKey: '$productSubLineSearchKey',
                          productSearchKey: '$productSearchKey',
                          productDescriptionSearchKey: '$productDescriptionSearchKey',
                          selectedPriceBooks: '$selectedPriceBooksStr'})

                          getWrapperList(result){
                            this.wiredResults=result;
                            if (result.data)
                            {
                                this.columns = result.data.columnList;
                                this.wrapperList = result.data.dataList2;
                              
                            }  
                            else if(result.error)
                            {
                                this.error = result.error;
                            }

    }

Thanks very much for getting through this long post, and I truly appreciate any help that could be provided.