Reputation: 1524
I have used mat-table
in my Angular 5 project. The table consists of various data and option of delete. When data gets deleted, it doesn't disappear from the table unless the page is reloaded. I had used splice
in another data table used from a package and it worked fine, but in mat-table
the same could not be done.
My table's view:
<h5>User List </h5>
<div class="example-container mat-elevation-z8">
<div class="example-header">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" matInput placeholder="Filter">
</mat-form-field>
</div>
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> User ID</mat-header-cell>
<mat-cell *matCellDef="let item">
{{item.id}}
<span (click)="editUserData(item)"> edit </span>
<span (click)="viewUserData(item)"> view </span>
<span (click)="confirmDelete(item)"> delete </span>
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Name</mat-header-cell>
<mat-cell *matCellDef="let item"> {{item.full_name}}</mat-cell>
</ng-container>
<ng-container matColumnDef="phone">
<mat-header-cell *matHeaderCellDef mat-sort-header> Mobile / Phone</mat-header-cell>
<mat-cell *matCellDef="let item"> {{item.mobile}}</mat-cell>
</ng-container>
<ng-container matColumnDef="email">
<mat-header-cell *matHeaderCellDef mat-sort-header> Email</mat-header-cell>
<mat-cell *matCellDef="let item"> {{item.email}}</mat-cell>
</ng-container>
<ng-container matColumnDef="organization">
<mat-header-cell *matHeaderCellDef mat-sort-header> Organization</mat-header-cell>
<mat-cell *matCellDef="let item"> {{item.organization}}</mat-cell>
</ng-container>
<ng-container matColumnDef="status">
<mat-header-cell *matHeaderCellDef mat-sort-header> status</mat-header-cell>
<mat-cell *matCellDef="let item"> {{item.status}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator #paginator
[pageSize]="10"
[pageSizeOptions]="[5, 10, 20]"
[showFirstLastButtons]="true">
</mat-paginator>
</div>
<p-confirmDialog header="Confirmation" icon="fa fa-question-circle" width="425"></p-confirmDialog>
My component's ngOnit portion where I have set the datasource:
ngOnInit()
{
this.appService.getUserDataList().subscribe(res => {
this.employeeTemp = res;
console.log('THIS IS AGAIN ME', this.employeeTemp);
this.dataSource = new MatTableDataSource(this.employeeTemp);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
}
My confirmDelete
function:
confirmDelete(item)
{
this.confirmationService.confirm({
message: 'Are you sure you want to delete this Employee?',
header: 'Confirmation',
accept: () => {
this.appService.deleteUser(item.id).subscribe(res => {
// Splice Or something so the page doesnt reload but the data gets removed from the view.
const index = this.dataSource.indexOf(item);
this.dataSource.splice(index, 1);
this.flashMsg.flashMsg('success', 'Deleted', 'User has been deleted.'); // this.EmployeeListComponent();
},
err => {
this.flashMsg.flashMsg('error', 'Error', 'User has not been deleted.');
});
},
reject: () => {
},
});
}
The value stored in item
of confirmDelete
function:
address :" "
email:"[email protected]"
full_name:"asdf asdf"
id:"[email protected]"
mobile:"12345678"
organization:"VURUNG TECH"
status:"Active"
updated_at:"2018-06-20T05:15:52.000Z
I get the success flashMessage
displayed but the splice doesnot work.
Upvotes: 2
Views: 5230
Reputation: 414
Please reproduce these steps exactly.
-> Step#1
dataSource: any = new MatTableDataSource()
-> Step#2 Splice at index
this.dataSource.data.splice(currentIndex, 1);
-> Step#3 then to update view
this.dataSource._data.next(this.dataSource.data)
Very important: In order to avoid this error
"Property '_data' is private and only accessible within class 'MatTableDataSource"
Don't forget any with dataSource:
step#1 'dataSource : any'
-> Detail of step #2 (information only)
When I console, I see there behaviour '_data'
subject property of dataSource. So I update it, so that the view shall update.
Upvotes: 0
Reputation: 32535
Try to invoke change detection run after model changes.
constructor(private cdr:ChangeDetectionRef)
and
this.appService.deleteUser(item.id).subscribe(res => {
....
this.cdr.detectChanges();
....
},
Upvotes: 0
Reputation: 5462
Try by resetting datasource
or updating data
of datasource
as:
confirmDelete(item) {
this.confirmationService.confirm({
...
accept: () => {
this.appService.deleteUser(item.id).subscribe(res => {
this.employeeTemp = this.employeeTemp.filter(employee => employee.id != item.id)
this.dataSource = new MatTableDataSource(this.employeeTemp);
//this.dataSource.data = this.employeeTemp; <=== You can also change only data
...
},
...
}
...
});
}
Upvotes: 3
Reputation: 4208
Make a reference to <mat-table>
using the hashtag: <mat-table #table [dataSource]="dataSource">
.
Get the reference inside the component ts:
@ViewChild('table') table: MatTable<any>;
after this.dataSource.splice(index, 1);
call:
this.table.renderRows();
Upvotes: 1