2

My question: I am stuck at the angular material table. I installed it and created my first table. As well i created a function which should delete the last row but the table does not refresh at all until i make a site change or something like this.

Question: How can i refresh the table after i deleted / added / edited data?

this.table.renderRows(); isnt working

Code below:

  1. test-table-datasource.ts
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { map } from 'rxjs/operators';
import { Observable, of as observableOf, merge } from 'rxjs';


export interface TestTableItem {
  name: string;
  id: number;
}

const EXAMPLE_DATA: TestTableItem[] = [
  {id: 1, name: 'Hydrogen'},
  {id: 2, name: 'Helium'},
  {id: 3, name: 'Lithium'},
  {id: 4, name: 'Beryllium'},
  {id: 5, name: 'Boron'},
  {id: 6, name: 'Carbon'},
  {id: 7, name: 'Nitrogen'},
  {id: 8, name: 'Oxygen'},
  {id: 9, name: 'Fluorine'},
  {id: 10, name: 'Neon'},
  {id: 11, name: 'Sodium'},
  {id: 12, name: 'Magnesium'},
  {id: 13, name: 'Aluminum'},
  {id: 14, name: 'Silicon'},
  {id: 15, name: 'Phosphorus'},
  {id: 16, name: 'Sulfur'},
  {id: 17, name: 'Chlorine'},
  {id: 18, name: 'Argon'},
  {id: 19, name: 'Potassium'},
  {id: 20, name: 'Calcium'},
];

export class TestTableDataSource extends DataSource<TestTableItem> {
  data: TestTableItem[] = EXAMPLE_DATA;
  paginator: MatPaginator | undefined;
  sort: MatSort | undefined;

    
  constructor() {
    super();
  }

  connect(): Observable<TestTableItem[]> {
    if (this.paginator && this.sort) {
      // Combine everything that affects the rendered data into one update
      // stream for the data-table to consume.
      return merge(observableOf(this.data), this.paginator.page, this.sort.sortChange)
        .pipe(map(() => {
          return this.getPagedData(this.getSortedData([...this.data ]));
        }));
    } else {
      throw Error('Please set the paginator and sort on the data source before connecting.');
    }
  }

  
  private getPagedData(data: TestTableItem[]): TestTableItem[] {
    if (this.paginator) {
      const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
      return data.splice(startIndex, this.paginator.pageSize);
    } else {
      return data;
    }
  }

  private getSortedData(data: TestTableItem[]): TestTableItem[] {
    if (!this.sort || !this.sort.active || this.sort.direction === '') {
      return data;
    }

    return data.sort((a, b) => {
      const isAsc = this.sort?.direction === 'asc';
      switch (this.sort?.active) {
        case 'name': return compare(a.name, b.name, isAsc);
        case 'id': return compare(+a.id, +b.id, isAsc);
        default: return 0;
      }
    });
  }
}

function compare(a: string | number, b: string | number, isAsc: boolean): number {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
  1. test-table-component.ts
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTable, MatTableDataSource } from '@angular/material/table';
import { TestTableDataSource, TestTableItem } from './test-table-datasource';
import {CdkTableModule} from '@angular/cdk/table';

@Component({
  selector: 'app-test-table',
  templateUrl: './test-table.component.html',
  styleUrls: ['./test-table.component.css']
})
export class TestTableComponent implements AfterViewInit {
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;
  @ViewChild(MatTable) table!: MatTable<TestTableItem>;
  dataSource: TestTableDataSource;

  displayedColumns = ['id', 'name'];

  constructor() {
    this.dataSource = new TestTableDataSource();
  }

  ngAfterViewInit(): void {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator;
    this.table.dataSource = this.dataSource;
  }
  
  removeData(){
    console.log(this.dataSource.data.length);
    this.dataSource.data.pop();
    console.log(this.dataSource.data.length);
    this.table.renderRows();
  }
}
  1. test-table-component.html
  <div>
    <button (click)="removeData()">delete</button>
  </div>
</div>

<div class="mat-elevation-z8">
  <table mat-table class="full-width-table" matSort aria-label="Elements">
    <!-- Id Column -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Id</th>
      <td mat-cell *matCellDef="let row">{{row.id}}</td>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
      <td mat-cell *matCellDef="let row">{{row.name}}</td>
    </ng-container>

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

  <mat-paginator #paginator
      [length]="dataSource?.data?.length"
      [pageIndex]="0"
      [pageSize]="10"
      [pageSizeOptions]="[5, 10, 20]"
      aria-label="Select page">
  </mat-paginator>
</div>
Panter
  • 21
  • 3
  • what is the question? Can you please update the question with more details? – Pankaj Parkar Jul 26 '22 at 22:04
  • Thank you for the hint i made an update. – Panter Jul 26 '22 at 22:08
  • Did you check this: https://stackoverflow.com/questions/46746598/angular-material-how-to-refresh-a-data-source-mat-table – paranaaan Jul 27 '22 at 02:32
  • Does this answer your question? [Angular + Material - How to refresh a data source (mat-table)](https://stackoverflow.com/questions/46746598/angular-material-how-to-refresh-a-data-source-mat-table) – paranaaan Jul 27 '22 at 02:32
  • Thank you guys for your answers. So i have to use: dataSource = new MatTableDataSource(); instead of this: this.dataSource = new TestTableDataSource(); and than i can use it like in the other question? – Panter Jul 27 '22 at 09:23

1 Answers1

0

You have to make an EXAMPLE_DATA.pop()

and then a this.dataSource.data= EXAMPLE_DATA;

This solution work perfely for me