Reputation: 27
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.
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!
Upvotes: 1
Views: 10069
Reputation: 1898
in your "angular-table.component.html" you add a button in a row and to get the id;
<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>
<div class="example-element-description">
<button
mat-raised-button
color="warn"
(click)="handelDelete(item.id)"
>
Delete
</button>
</div>
</table>
<button (click)="ADD1()">Add1</button>
<button (click)="ADD2()">Add2</button>
In your angular-table.component.ts, add the method to remove the element form data[] and refresh the table data.
export class AngularTableComponent implements OnInit {
constructor() { }
ngOnInit() {
// remove :void type
// refrech the data with OnInit
this.data = this.data
}
amount: number;
data: any = [];
id: number = 2;
title: string = 'test';
displayedColumns: string[] = ['title', 'id', 'delete'];
constructor() { }
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);
}
handelDelete(pId) {
// to delete the element by id
this.data = this.data.filter(element => element == pId);
}
removeCart(index: number){
this.data.splice(index, 1);
}
}
Upvotes: 1
Reputation: 2723
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.
Upvotes: 4