Search code examples
angularprimengprimeng-datatable

Why array.push does not work on collection holding table data in Angular4 and PrimeNG?


So having following markup:

<p-dataTable
                                    selectionMode="single"
                                    [(selection)]="selectedUsers"
                                    dataKey="id"
                                    [value]="users"
                                    [rows]="25" [paginator]="users.length>25" [pageLinks]="3"
                                    [rowsPerPageOptions]="[10,25,50,100]"
                                   >

I am doing the following action to add record to table

applySelectedUsers() {
    // this.users.push(this.selectedUserToAdd);
    let arr=[];
    arr.push(this.selectedUserToAdd);
    this.users=this.users.concat(arr);
    this.selectedUserToAdd=null;
    this.hideUsersDialog();
}

My question is, why commented line does not work? Record is not visible in table despite console.log(this.users) showing that collection is growing after each push


Solution

  • PrimeNG's datable looks for changes in reference so it expects immutable data. If you don't need to take advantage over what immutability gives you just set [immutable] property of p-dataTable to false. But keep in mind that it will force the datatable to check the collection you bound to the [value] property on every ngDoCheck lifecycle resulting in performance drop.

    You can nicely see the reason why it's not changing in the view in the source code

     set value(val:any[]) { // this will be triggered only by reassigning to this.users
            if(this.immutable) {
                this._value = val ? [...val] : null;  
                this.handleDataChange();
            }
            else {
                this._value = val;
            }
    
            this.valueChange.emit(this.value);
        }
    

    now if you never reassign and set [immutable] to false it will check the differences in the lifecycle

        ngDoCheck() {
        if(!this.immutable) {
            let changes = this.differ.diff(this.value);
            if(changes) {
                this.handleDataChange();
            }
        }
    }
    

    I hope I helped. Have a nice day and don't React :)