Rudy Dudy2019-05-23 13:15:55
Rudy Dudy, 2019-05-23 13:15:55

Angular material table - multiple tables per page, table update after restAPI response, how to do without code duplication?

Hello! Help with code optimization.
There is a view where info is displayed in tables, I use the material for this task.
one table displays information about users, and the other about admins. in the table ID, firstName, lastName, email, etc.
There is a button to update the table, which makes a request to the backend, and pulls out data about users / admins.
The table has checkboxes + filtering. The problem is that I don't like the implementation of the code... each table uses different variables, methods, etc., which aren't really that different.

dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
selection = new SelectionModel<PeriodicElement>(true, []);
dataSourceAdmin = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA_ADMIN);
selectionAdmin = new SelectionModel<PeriodicElement>(true, []);

isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  masterToggle() {
    this.isAllSelected() ?
        this.selection.clear() :
        this.dataSource.data.forEach(row => this.selection.select(row));

  checkboxLabel(row?: PeriodicElement): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;

 isAllSelectedForAdmin() {
    const numSelected = this.selectionAdmin.selected.length;
    const numRows = this.dataSourceAdmin.data.length;
    return numSelected === numRows;
  masterToggleForAdmin() {
    this.isAllSelected() ?
        this.selectionAdmin.clear() :
        this.dataSourceAdmin.data.forEach(row => this.selectionAdmin.select(row));

  checkboxLabelForAdmin(row?: PeriodicElement): string {
    if (!row) {
      return `${this.isAllSelectedForAdmin() ? 'select' : 'deselect'} all`;
    return `${this.selectionAdmin.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;

And so on... As you can see, the code is heavily duplicated, and it already looks confusing, and if one more table is added, it will be even worse.
There was an idea to make the table a separate component, but the tables have different fields (the admin has more, the user has less, and many fields are different, etc.)
When new data comes from the backend - I need to update the table - what is the best way to do this? Because right now it looks like this:
dataSource = new MatTableDataSource<PeriodicElement>(NEW DATA FROM RESPONSE);
selection = new SelectionModel<PeriodicElement>(true, []);

That is, I constantly overwrite the dataSource, throw off the SelectionModel, and so on.
Is there any way to optimize? So that the methods are universal for tables, and the update is more elegant.
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
p1plop, 2019-07-19

To avoid code duplication, you can change the functions to receive objects of a specific table as arguments in them, in which case one function can be used for both tables

isAllSelected(selection, dataSource) {
    const numSelected = selection.selected.length;
    const numRows = dataSource.data.length;
    return numSelected === numRows;

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question