1

I want to build a table where every column is a response from an API call and contains some elements. I tried different approaches with material table but nothing seems to work. The problem comes from the fact that I try to build it on columns and not on rows (there are different number of elements on every col)

I've also tried with a simple table and it works but then the view doesn't look like it should. Every column is wrapped in an <ng-container> and it should be displayed as a new column, but it displays them on the same column. I've also tried an approach using divs and that works fine but then I can not make the header of the table to be sticky and fixed when I scroll down. (also, is not a good idea using divs inside a table) This is how my table looks now, being the best variant so far:

 <table class="mat-table">
      <ng-container *ngFor="let elem of selectedCheckValues">
        <th class="mat-header-cell">{{ elem.name }}</th>
        <tr id="{{element}}" *ngFor="let element of elem.items; let idx=index;" (click)="onRowClick(elem, element)">
          <td class="mat-cell">{{element}}</td>
        </tr>
      </ng-container>
    </table>

And this is how my data looks like:

export interface SelectedCheckValues {
  name: string;
  items: string[];
}

Where name should be the table header and items the elements from the column.

Catleen
  • 81
  • 1
  • 5

2 Answers2

1

If you want to distribute a series of calls in columns in a mat-table you need "create" a DataSource with the columns.

I made a simple example. In this I imagine you get the data using a forkJoin so you can have something like

  dataSource:any[] = [];
  data=[0,1,2]
  headers:string[]=[]
  constructor(private dataService:DataService){}
  ngOnInit(){

    //we make a "typical" forkJoin where transform the "data" in an
    //array of "Observables" and use forkJoin
    forkJoin(this.data.map(x=>this.dataService.getData(x)))
    .subscribe((res:any[])=>{
       //when we has the response we "formed" the dataSource
       let i=0;
       let goon=true;
       this.headers=res.map(x=>x.name)
       while(goon)
       {
          const items=res.map(x=>x.items[i])
          goon=items.find(x=>x!==null)
          this.dataSource.push(items)
          i++;
       }
    })
  }

And a .html

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  <ng-container *ngFor="let header of headers;let i=index" [matColumnDef]="header">
    <th mat-header-cell *matHeaderCellDef>{{header}}</th>
    <td mat-cell *matCellDef="let element"> {{element[i]}} </td>
  </ng-container>


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

See the stackblitz

BTW, mat table with a sticky it's only .css, so you can take as approach use a normal table and the .css to sticky the "header"

Update: it's difficult for me imagine how you get your data, if you get it using three calls to an api

getMFTNO() //return some like [101,102,103]
getDF_RESULT() //return some like ["DL","FM","FT"]
getPERSNO() //return some like [0,000000,0000001]

And all the apis return the same number of elements, the idea is use a forJoin of the three calls and map to an array of object

forkJoin([this.getMFTNO(),this.getDF_RESULT(),this.getPERSNO()])
      .pipe(
        map(([mftno,dfResult,persno]:[any[],any[],any[]])=>{
          return mftno.map((x,index)=>(
          { 
            mftno:x,
            dfResult:dfResult[index],
            persno:persno[index]
          }
        ))
        }))

NOTE: I updated the stackblitz to take account this

Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Thank you for your answear but it doesn't work. Firstly, if I use your example, the size of the columns will be equal with the size of the headers array which is not good (i have different sizes columns). Also, with your approach, the data is constructed on rows and not on columns. – Catleen May 26 '21 at 09:29
  • @Catleen, how you get the "data"? I update the answer in the case we has three calls (but in this case the calls are fixed). Sorry if I only I get muddle you :( – Eliseo May 26 '21 at 11:07
0

A little snip from my table with how it looks like.

enter image description here

instead of

enter image description here

Catleen
  • 81
  • 1
  • 5