1

So I am trying to add a new line in a table which is populated from an API but it looks that I miss something. Here is my code:

HTML:

<button mat-flat-button color="primary" class="btn-add" 
    (click)="addRow()" 
    [disabled]="isLoading">ADD</button>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z2" *ngIf="show">
  <ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
    <th mat-header-cell *matHeaderCellDef>{{column}}</th>
    <td mat-cell *matCellDef="let element; index as i;">
      <span *ngIf="element.editing; then editBlock else displayBlock"></span>
      <ng-template #displayBlock>{{element[column]}}</ng-template>
      <ng-template #editBlock>
        <mat-form-field appearance="fill">
          <input matInput [(ngModel)]="element[column]">
        </mat-form-field>
      </ng-template>
    </td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

TS file:

displayedColumns: string[] = [];
dataSource: any;

addRow() {
  console.log("Adding new row");
  let newRow = {
    editing: true
  };
  this.displayedColumns.forEach(x => newRow[x] = "");
  this.dataSource.push(newRow);
}

2 Answers 2

1

Reference to the variable dataSource is not updated. Angular change detector not always can (while sometimes can) recognize such changes. Creating new reference (new array in this case) should solve this issue:

addRow() {
  let newRow = { editing: true };
  this.displayedColumns.forEach(x => newRow[x]="");
  this.dataSource = [...dataSource, newRow];
}
Sign up to request clarification or add additional context in comments.

2 Comments

You can omit the first two lines I guess, +1
You are welcome @DanutPopescu! Don't forget to accept an answer if it solves your question. stackoverflow.com/help/someone-answers
0

You are missing the table.renderRows() call

Documentation:

If a data array is provided, the table must be notified when the array's objects are added, removed, or moved. This can be done by calling the renderRows() function which will render the diff since the last table render. If the data array reference is changed, the table will automatically trigger an update to the rows.

HTML

<table #elementTable mat-table class="mat-elevation-z2"
    *ngIf="show"
    [dataSource]="dataSource">

TS

@ViewChild('elementTable') matTable: MatTable<any>;

And in addRow() function

addRow() {
  console.log("Adding new row");
  const newRow: any = {
    column: '',
    editing: true
  };
  this.dataSource.push(newRow);
  this.table.renderRows();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.