0

I have an Angular 13 app & building a common reusable component named app-table

html

    <table class="table table-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>DOB</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of tableItems">
            <td> {{ item.name }}</td>
            <td> {{ item.email } </td>
            <td> {{ item.dob }} </td>
        </tr>
    </tbody>
</table>

component.ts

    import { Component, Input, OnInit} from '@angular/core';
    import { TableItem } from './model/tableItem';

    @Component({
     selector: 'app-table',
     templateUrl: './table.component.html',
     styleUrls: ['./table.component.css'],
    })

    export class TableComponent implements OnInit {
     @Input() tableItems: TableItem[] = [];
   
     constructor() {}

     ngOnInit(): void {}
     }

Currently, this is reusable across 4-5 places, however reusability of this component is tied to name, email, dob fields. I want to make it generic so that any model could be linked to this component & can be reused across the app.

Please suggest. Thanks!

2
  • 1
    I use this datatable, which allows you to fully customize the cells (eg. put a routerLink in one cell, checkbox in another, ...). You can use it as inspiration Commented Aug 4, 2022 at 18:25
  • I completely agree with Munzer. Please consider "upvoting" and/or "accepting" his response. See also: damirscorner.com/blog/posts/… Commented Aug 4, 2022 at 18:28

2 Answers 2

3

There are a lot of ways to do it, the simplest one would be add another input which accepts a list of columns, then you can populate your table header based on that list. something like this.

    <table class="table table-striped">
      <thead>
          <tr>
            <ng-container *ngFor="let column of columns">
              <th>{{column}}</th>
            </ng-container>
          </tr>
      </thead>
      <tbody>
          <tr *ngFor="let item of tableItems">
            <ng-container *ngFor="let column of columns">
              <td>{{item[column]}}</td>
            </ng-container>
          </tr>
      </tbody>
    </table>  

and your component will look like this.

    columns = ['name','email','dob']
    tableItems = [
      {
        name: 'test',
        dob: '31/12/1990',
        email: '[email protected]'
      }
    ];

but table components are really difficult to maintain and extend, they require a lot of effort, it's not something you casually do. I would suggest finding a library that built a really good table component and using it, depending on your requirements, few examples would be ngx easy table, angular cdk table, and so on.

Sign up to request clarification or add additional context in comments.

1 Comment

what to do in case of if array contains nested object?
1

You can get the column names from object keys and iterate over them using *ngFor, for example:

In your TableComponent template file

<table>
  <thead>
    <tr>
      <th *ngFor="let header of data[0] | keyvalue: sortNull">{{ header.key }}</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let row of data">
      <td *ngFor="let cell of row | keyvalue: sortNull">{{ cell.value }}</td>
    </tr>
  </tbody>
</table>

And in typescript file

export class TableComponent {
  @Input() data: any[] = [];

  sortNull() { return 0; }
}

sortNull() is just a compartor function that always return 0 to maintain the order of insertion for your key/value pairs

And for usage

@Component({
  selector: 'app-user-list',
  template: `<app-table [data]="data"></app-table>`
})
export class UserListComponent {

  data = [ 
    { name: 'John', email: '[email protected]', dob: '2001/01/01' }, 
    { name: 'Jane', email: '[email protected]', dob: '2002/02/02' }, 
    { name: 'Kane', email: '[email protected]', dob: '2003/03/03' }, 
  ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.