Search code examples
angulartypescriptangular-materialmat-table

Angular how to delete a row in mat table?


I can't use *ngFor in my angular mat table, or I just don't have the knowledge for that. I would really appreciate it if anyone can help me out?

I want to delete a row within an array for example with a button and then list it on my table, but it just doesn't work. Therefore I want to use *ngFor to display the table data, but if I click that ADD button it adds another row without data inside.

enter image description here

This is what I got so far:

angular-table.component.html

<table mat-table *ngFor="let item of data" class="mat-elevation-z8" matSort>

    <ng-container matColumnDef="title">
        <th mat-header-cell *matHeaderCellDef>Title</th>
        <td mat-cell *matCellDef> {{item.title}} </td>
    </ng-container>

    <ng-container matColumnDef="id" id="id">
        <th mat-header-cell *matHeaderCellDef>ID</th>
        <td mat-cell *matCellDef> {{item.id}}</td>
    </ng-container>

    <ng-container matColumnDef="delete">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Test</th>
        <td mat-cell *matCellDef> 
            <mat-icon (click)="removeCart(i)" class="removeCart">close</mat-icon>
        </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

<button (click)="ADD1()">Add1</button>
<button (click)="ADD2()">Add2</button>

angular-table.component.ts

export class AngularTableComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  amount: number;
  data: any = [];
  id: number = 2;
  title: string = 'test';

  displayedColumns: string[] = ['title', 'id', 'delete'];


  ADD1(){
    const id = this.id;
    const title = this.title;

    const newData = {
      id,
      title
    }
    this.data.push(newData);
    console.log(this.data);
   }


  ADD2(){
    const id = this.id = 7;
    const title = this.title = "Hello";

    const newData = {
      id,
      title
    }
    this.data.push(newData);
    console.log(this.data);
   }


  removeCart(index: number){
    this.data.splice(index, 1);
  }
}

I made a StackBlitz, but sadly it doesn't work I couldn't get it to work to import the modules, I tried for very long. https://stackblitz.com/edit/add-angular-material-o2pu6c?file=src%2Fmain.ts

Thank you!


Solution

  • First, at <table mat-table *ngFor="let item of data", it will repeat the table with header all the time. It won't show the data.

    So, you better use MatTableDataSource.

    dataSource: MatTableDataSource<any> = new MatTableDataSource<any>([]);
    

    Then, you can assign your data to the dataSource's data.

    this.dataSource.data = this.data;
    

    Now, your table will be like this:

    <table mat-table class="mat-elevation-z8" [dataSource]="dataSource" matSort>
    

    And, your column definitions will be like this:

    <ng-container matColumnDef="title">
         <th mat-header-cell *matHeaderCellDef>Title</th>
         <td mat-cell *matCellDef> {{item.title}} </td>
    </ng-container>
    

    Since, you want to delete a row, you need a button and index of the row to delete the row.

    <ng-container matColumnDef="delete">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Test</th>
        <td mat-cell *matCellDef="let i = index"> 
            <button mat-icon-button class="removeCart" (click)="removeCart(i)" >
               <mat-icon>close</mat-icon>
            </button>
        </td>
    </ng-container>
    

    Working demo at StackBlitz.