Search code examples
angularprimeng

Pushing element on the array is not updating the primeng p-table


I am using the primeng p-table to show the data in table format. I bind the property "certifications" to value. This gird has crud operation so we can edit or add the data in grid. So whenever we add the element and push the data to "certifications" it doesn't reflect on UI. Angular Version 13 Primeng Version 13.

Earlier it was working fine when both are on 8th version but after upgrading to 13 it is breaking.

`

<p-table class="dataGrid" [value]="certifications" [paginator]="false" editMode="row" dataKey="id" sortField="id"
        sortOrder="-1" [resizableColumns]="true" columnResizeMode="expand">
        <ng-template pTemplate="emptymessage" let-columns>
          <tr>
              <td [attr.colspan]="6">
                  No records found
              </td>
          </tr>
      </ng-template>
        <ng-template pTemplate="header">
          <tr>
            <th pResizableColumn>Certification Type</th>
            <th pResizableColumn>State</th>
            <th pResizableColumn>Certification No</th>
            <th pResizableColumn>Expiration Date</th>
            <th pResizableColumn>Remarks</th>
            <th *ngIf="canEdit"></th>
          </tr>
        </ng-template>
        <ng-template pTemplate="body" let-rowData let-columns="columns">
          <tr [pSelectableRow]="rowData" *ngIf="!rowData.deleted" >
              <td>{{ (rowData.certification) ? rowData.certification.name : ''}}</td>
            <td>
              {{ (rowData.stateProvince) ? rowData.stateProvince.name : ''}}
            </td>
            <td>{{rowData.certificationNo}}</td>
            <td>{{rowData.expirationDate | date:'MM/dd/yyyy'}}</td>
            <td>{{rowData.remarks}}</td>
            <td class="align-center">
              <button *ngIf="canEdit" pButton type="button" icon="pi pi-pencil" class="ui-button-info edit-button"
                (click)="onEdit(rowData)"></button>
              <button *ngIf="canEdit" pButton type="button" icon="pi pi-trash"
                class="ui-button-danger" (click)="onDelete(rowData)"></button>
            </td>
          </tr>
        </ng-template>
      </p-table>

const certData = Mapper.mapTo(formData, ResourceCertificationDto);
    certData.certificationId = formData.certification.id;
    certData.stateProvinceId = !gh.isUoN(formData.stateProvince) ? formData.stateProvince.id : null;
    if (formData.id === 0) {
      certData.id = ResourceCertificationComponent.newCertificateId--;
      this.certifications.push(certData);
    } else {
      const index = this.certifications.findIndex(p => p.id === formData.id);
      this.certifications[index] = certData;
   }

`


Solution

  • The answer to your issue can be found here: https://www.primefaces.org/primeng/table

    Change Detection Table may need to be aware of changes in its value in some cases such as reapplying sort. For the sake of performance, this is only done when the reference of the value changes, meaning a setter is used instead of ngDoCheck/IterableDiffers which can reduce performance. So when you manipulate the value such as removing or adding an item, instead of using array methods such as push and splice, instead create a new array reference using a spread operator or similar.

    This means you should change your code from

    this.certifications.push(certData);

    to

    this.certifications = [...this.certifications, certData]

    Same applies when you want to update an item. Change

    this.certifications[index] = certData;

    to

    this.certifications[index] = certData;
    this.certifications = [...this.certifications]