[SalesForce] LWC – Preselect all rows in the Data Table

I'm trying to figure out how to pre-select all of the rows in my Data-table. According to this documentation, we can select rows programmatically. However, it does not explicitly show how to select all of the rows for a Data-table. Which is basically what I'm aiming to do. For reference, here are my codes:

HTML

<template if:true={oppLines}>
    <lightning-datatable
            key-field="Id"
            data={oppLines}
            columns={columns}
            onrowselection={selectedRowsEvent}
            selected-rows={preSelectedRows} 
            resize-column-disabled=true>    
    </lightning-datatable>
</template>
<template if:true={error}>
    <p>{oppLines.error}</p>
</template>

JS

I use @wire to get data from an Apex controller and basically prepare my data for the Data-table as shown below.

@track oppLines;
@track preSelectedRows;

@wire(getOppLines, { searchKey: '$searchKey' }) wired(result) {
    this.refreshTable = result;
    if (result.data) {
      let preparedOppLines = [];
      result.data.forEach(oppLine => {
          let preparedOppLine = {};
          preparedOppLine.Id = oppLine.Id;
          preparedOppLine.Name = oppLine.Name;
          // ... bunch of other field assignments here ...
          preparedOppLines.push(preparedOppLine);
          });
          this.oppLines = preparedOppLines;

          // This is what I use to preselect my rows
          var setRows = [];
          for (var i = 0; i < oppLines.length; i++){
              setRows.push(oppLines[i].Id);
          }
          this.preSelectedRows = setRows;
     }
    if (result.error) {
        this.error = result.error;
    }
}

Please notice that the block of code you see below is what I am using to get my rows (also included part of the code above). Presumably, this is where I would get the number of rows for my Data-table which is why I've included it right after my @wire because as I understand – the table must exist first, thus we can't place it in the connectedCallback (Please correct me if I'm wrong on this) to pre-select the rows upon loading.

var setRows = [];
for (var i = 0; i < oppLines.length; i++){
    setRows.push(oppLines[i].Id);
}
this.preSelectedRows = setRows;

Sadly, I'm going nowhere with this setup. What am I doing wrong exactly? And can this get any simpler?

Any help is much appreciated. Thank you!

UPDATED with sfdcfox's answer:

// JS
@track oppLines = []; // added array
@track preSelectedRows = []; // added array

        @wire(getOppLines, { searchKey: '$searchKey' }) wired(result) {
                this.refreshTable = result;
                if (result.data) {
                  let preparedOppLines = [];
                  result.data.forEach(oppLine => {
                      let preparedOppLine = {};
                      preparedOppLine.id = oppLine.Id; // changed to lowercase id
                      preparedOppLine.Name = oppLine.Name;
                      // ... bunch of other field assignments here ...
                      preparedOppLines.push(preparedOppLine);
                      });
                      this.oppLines = preparedOppLines;

                      // This is what I use to preselect my rows
                      setTimeout(() => this.preSelectedRows = this.oppLines.map(record=>record.id)); // changed to lowercase id
                     } 
                    if (result.error) {
                        this.error = result.error;
                    }
            }

// HTML
<template if:true={oppLines}>
        <lightning-datatable
                key-field="id" // changed to lowercase id
                data={oppLines}
                columns={columns}
                onrowselection={selectedRowsEvent}
                selected-rows={preSelectedRows} 
                resize-column-disabled=true>    
        </lightning-datatable>
        </template>
        <template if:true={error}>
             <p>{oppLines.error}</p>
        </template>

Best Answer

It appears you can't select the values until after the table renders. Try the following change:

// This is what I use to preselect my rows
setTimeout(
  () => this.preSelectedRows = oppLines.map(record=>record.Id)
);

See this playground.

Related Topic