Checkbox rendering not updating with state updates

I am implementing a basic table with static data which allows user to select and deselect rows. The state is updating fine but its causing rendering issue where checkbox selection is not working when Select All checkbox is selected. It throws

ember.js:1538 Uncaught (in promise) TypeError: Cannot convert undefined or null to object error.

This is my Application.hbs code:


<DownloadableFiles @files={{this.model}}/>

DownloadableFiles.hbs

<tbody>
            {{#each @files as |file|}}
            <tr class="grid-item">
<td><input type="checkbox"
                class="select-box"
                checked={{if this.selectedFiles (this.selectedFiles.includes file) false}}
                {{on "change" (fn this.toggleFileSelection file)}}></td>
                <td>{{file.name}}</td>
                <td>{{file.device}}</td>
                <td>{{file.path}}</td>
                <td>{{file.status}}</td>

And this is my logic:
 @tracked selectedFiles = [];
  @tracked allSelected = false;

  get hasSelectedFiles() {
    return this.selectedFiles.length > 0;
  }

  toggleSelectAll = (event) => {
      this.allSelected = !this.allSelected;
    if (this.allSelected) {
      this.selectedFiles = [...this.args.files];
    
    } else {
      this.selectedFiles = [];
    }
    
  };

  @action
  toggleFileSelection (file) {
        if (this.selectedFiles.includes(file)) {
            this.selectedFiles = this.selectedFiles.filter((f) => f !== file);
          } else {
            this.selectedFiles =  [...this.selectedFiles, file];
          }
          //updates the allSelected state to true if all files are selected by the user.
          //This keeps the "Select All" checkbox in sync with the actual selection state.
          this.allSelected = this.selectedFiles.length === this.args.files.length;    
  };

This line of code is giving error: checked={{if this.selectedFiles (this.selectedFiles.includes file) false}} Please help!

where is file defined?

I updated my code to show how I defining file that is being passed from applcation.hbs file.

 <tbody>
            {{#each @files as |file|}}
            <tr class="grid-item">
                <td><input type="checkbox"
                class="select-box"
                checked={{if this.selectedFiles (this.selectedFiles.includes file) false}}
                {{on "change" (fn this.toggleFileSelection file)}}></td>
                <td>{{file.name}}</td>
                <td>{{file.device}}</td>
                <td>{{file.path}}</td>
                <td>{{file.status}}</td>
            </tr>
            {{/each}}
        </tbody>

I loaded your code into the limber repl, and was able to reproduce your problem with the condition.

You’ve run in to something we consider a bug, where in this.someObj.someMethod, someMethod loses its binding to someObj – this is planned to be fixed.

In the mean time, you can change your condition to:

checked={{this.hasSelected file}}

where

  hasSelected = (file) => this.selectedFiles.includes(file);

Thank you for the quick reply! The workaround solution works fine for now.

1 Like