0
votes

I would like to pass data (one row) into a component from its parent. This means that instead of the expected array-like object, the datasource is just an object. The table has three rows (including the header) and three columns (Attribute, Description, and Value).

The data interface:

export interface MyData {
  id: number,
  attr1Desc: string,
  attr1Value: number,
  attr2Desc: string,
  attr2Value: string
}

MyComponent.ts

export class MyComponent {
  @Input() row: MyData;

  displayColumns: string[] = ['Attribute_No', 'Desc', 'Value'];
  data: string[] = ['Character', 'World'];
  dataSource: MatTableDataSource(row); // Doesn't work

  getValue(index, type){
    return this.dataSource['attr'+(index+1)+type];
  }
}

MyComponent.html

<mat-table #table [dataSource]="dataSource">
  <ng-container matColumnDef="Attribute_No">
    <th mat-header-cell *matHeaderCellDef>Attribute No</th>
    <td mat-cell *matCellDef="let attr;let i = dataIndex;">
      <div *ngIf="i == 0">Character</div>
      <div *ngIf="i == 1">World</div>
    </td>
  </ng-container>
  <ng-container matColumnDef="Desc">
    <th mat-header-cell *matHeaderCellDef>Attribute Description</th>
    <td mat-cell *matCellDef="let attr_desc">{{getValue(i, 'Desc')}}</td>
  </ng-container>
  <ng-container matColumnDef="Value">
    <th mat-header-cell *matHeaderCellDef>Attribute Value</th>
    <td mat-cell *matCellDef="let attr_value">{{getValue(i, 'Value')}}</td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</mat-table>
2

2 Answers

0
votes

Firstly You need to wait the input is passed into your component before setting it in datasource, so you should use setter & getter.

Then datasource must be an array, so set [row].

_row: MyData;
get row(): MyData { return this._row; }
@Input('row')
set row(value: MyData) { 
  this._row = value;
  this.dataSource = new MatTableDataSource([this.row]);
}
0
votes

Map your object into an array before passing it onto the datasource.

If the data has always the same format you could just manually map it:

[
    {attrDesc: myData.attr1Desc, attrValue: myData.attr1Value},
    {attrDesc: myData.attr2Desc, attrValue: myData.attr2Value}
]

Otherwise, iterate through all the keys using Object.keys(myData) and push each pair of key-value as an element of the array.