Angular refresh table after delete record, using material table and rest api

16,409

Solution 1

There is no need to call the server for the updated data and download all the data again. Just call this function (below) and delete the row (splice) in the dataSource. Pass in the record id from your delete function and whatever the column name is where your id's are and magic happens. I include the paginator.

My StackBlitz for Angular Material Table has a working example. Also see my UpdateDatatableService which I use for CREATE AND UPDATE.

// Remove the deleted row from the data table. 
// Need to remove from the downloaded data first.

  private deleteRowDataTable (recordId, idColumn, paginator, dataSource) {
    this.dsData = dataSource.data;
    const itemIndex = this.dsData.findIndex(obj => obj[idColumn] === recordId);
    dataSource.data.splice(itemIndex, 1);
    dataSource.paginator = paginator;
  }

Solution 2

The Angular documentation shows there is a method, renderRows() which is available on the <table mat-table> elements. I was having the same problems, implemented this method, and it works great. I also learnt that you can optionally provide a data stream instead of simple data. Below solves the rendering of rows with simple data.

In your HTML template, give the <table mat-table> element a property binding:

<table mat-table [dataSource]="data" #myTable> <!-- #table binding here -->
  <!-- table cells content etc... -->
</table>

In your component class, link to the template property with @ViewChild, and call the renderRows() method when the table data changes.

import { MatTable } from '@angular/material/table';

export class MyComponent {
    @ViewChild('myTable') myTable: MatTable<any>; /*not exatly sure what the type should be set too */

    editDataMethod(){
        /* data handling logic */
        this.myTable.renderRows();

}
Share:
16,409
ufollettu
Author by

ufollettu

Updated on July 18, 2022

Comments

  • ufollettu
    ufollettu almost 2 years

    I have a material Table with expandable rows (https://material.angular.io/components/table/examples) and I want to manage delete into the table itself, so I create a delete button with a function that trigger the delete event. The api works, the record is correctly deleted, but the table is not refreshed after delete, and I want to implement this behaviour. Here a stackblitz with fake api: https://stackblitz.com/edit/angular-comzph

    I try, in my delete function to call ngOnInt and to navigate back to the same route, but nothing happens...

    deleteCustomer(id) {
     this.api.deleteCustomer(id)
      .subscribe(res => {
        alert(`cliente rimosso`);
        // TODO fix reload list after delete
        // this.router.navigate['/clienti'];
        this.ngOnInit();
      }, (err) => {
        console.log(err);
      }
     );
    }
    

    I try to use this solution too, but does not works. I try using ngOnChange and ngOnDestroy, but does not works too...

    Could someone help me?

    • Gijs Post
      Gijs Post almost 6 years
      Instead of completely refreshing or re-initializing the component, you could refresh the table dataset by calling your api to fetch the data again.
    • ufollettu
      ufollettu almost 6 years
      I try to call this.api.getCustomers() inside the deleteCustomer() method too, but is not working
    • Gijs Post
      Gijs Post almost 6 years
      Maybe using pipe? this.api.deleteCustomer(id).pipe(flatMap(_ => this.api.getCustomers)).subscribe(result => { // Assign to data })
    • ufollettu
      ufollettu almost 6 years
      no, do not works. maybe there's a problem with datasource property passed to mat-table html
    • ufollettu
      ufollettu almost 6 years
      I solve the problem using this solution: stackoverflow.com/questions/46746598/…, thanks for your help
  • Airo
    Airo almost 2 years
    The splice call returns the data without that row, if splicing the MatTableDataSource directly use - this.myDataSource = this.myDataSource.data.splice(index, 1);