Search code examples
angulartypescriptprimengprimeng-datatable

PrimeNG delete row of datatable


I have a problem deleting a row from a p-datatable.

TS

public files: UploadFile[] = [];
deleteAttachement(index) {

    if (this.files.length > 0) {
        for(let file2 of this.files) {
            if (file2.fileEntry.isFile) {
                const fileEntry = file2.fileEntry as FileSystemFileEntry;
                fileEntry.file((file: File) => {
                    console.log("-------------");
                    console.log("File: "+file.name);
                });
            }
        }

        this.files.splice(index, 1);

        for(let file2 of this.files) {
            if (file2.fileEntry.isFile) {
                const fileEntry = file2.fileEntry as FileSystemFileEntry;
                fileEntry.file((file: File) => {
                    console.log("_______________");
                    console.log("File: "+file.name);
                });
            }
        }
    }

}

HTML

<p-dataTable [value]="files" *ngIf="files.length > 0">
<p-column>
  <ng-template let-index="rowIndex" pTemplate type="body">
    <p-button (onClick)="deleteAttachement(index)" icon="fa fa-fw fa-close"></p-button>
  </ng-template>
</p-column>
</p-dataTable>

My code is logging the right things. It seems I am splicing right. BUT when I want to update the datatable in the view a change the line :

this.files = this.files.splice(index, 1);

But now it splices wrong and it doesn't remove the right row. Sometimes it deletes multiple rows and sometimes it removes nothing.


Solution

  • First thing you need to know is that for any updates that you would want to see in your p-dataTable there has to be a completely new array object that should be passed to its [value] parameter so that p-dataTable knows that it needs to re-render the table. This way we preserve immutability of objects and it has very good performance implications. Check this to know more on Immutability.

    splice updates the same array and thus doesn't create a new array object. See splice details here.

    When you do this.files.splice(index, 1), it updates the files array but this.files refers to the same object and hence it is not detected by PrimeNg.

    You would need to create a new array object each time you want to delete an item from it. This should work:

    this.files = this.files.slice(0, index).concat( this.files.slice(index+1) );
    

    slice doesn't update the array (this.files in this case), rather it creates a new copy of an array based on the given indices. So, here in the above line we create two sets of arrays. First array is from start to the given index (excluding the item at index) and the second array is from after the given index to the end of it. And then we concatenate both these arrays to get a completely new array excluding the item at position index.