Home > Software engineering >  best way to associate table header with table row in this data structure
best way to associate table header with table row in this data structure

Time:11-30

I Have the following table component with 2 data-structures that I need to form an HTML table from, one for the table schema (paymentTableMetadata) and one for the Data of the table by row and cell (paymentTableData). I hardcoded the data-structures for now to meet the scope of my problem.

When I write the table in HTML, the table data are not associated with the table headers:

here are my component.ts:

import { Component, OnInit } from '@angular/core';

import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { PaymentTableService } from 'src/app/services/payment-table-service/payment-table-service';
@Component({
  selector: 'payment-table',
  templateUrl: './payment-table.component.html',
  styleUrls: ['./payment-table.component.scss']
})
export class PaymentTableComponent implements OnInit {
  

  paymentTableMetadata = [
    {
        "cntrlFldCode": "Curr",
        "cntrlFldLabel": "Currency",
        "fieldDataType": "StringType",
        "cntrlFldTypeEnum": "InputField"
    },
    {
        "cntrlFldCode": "Amount",
        "cntrlFldLabel": "Amount",
        "fieldDataType": "DecimalType",
        "cntrlFldTypeEnum": "InputField"
    },
    {
        "cntrlFldCode": "Output",
        "cntrlFldLabel": "Result",
        "fieldDataType": "StringType",
        "cntrlFldTypeEnum": "OutputField"
    }
]




paymentTableData = {
    "dmnCode": "001",
    "dmnDsc": "Payment Amount Control",
    "dmnRows": [
        {
            "rowCode": "1",
            "rowDsc": "USD Amount <10,00",
            "rowOrder": 1,
            "processKey": "LowPaymentBpm",
            "outputValue": null,
            "cells": [
                {
                    "cellCode": "amt",
                    "cntrlFldCode": "Amount",
                    "cntrlFldLabel": "Amount",
                    "fieldDataType": "DecimalType",
                    "cntrlFldTypeEnum": "InputField",
                    "operatorEnum": "LessThanEqual",
                    "dateTypeEnum": null,
                    "value1TypeEnum": null,
                    "value1": "10000",
                    "value1Set": null,
                    "value1Offset": null,
                    "value2TypeEnum": null,
                    "value2": null,
                    "value2Set": null,
                    "value2Offset": null,
                    "errors": null
                },
                {
                    "cellCode": "curr",
                    "cntrlFldCode": "Curr",
                    "cntrlFldLabel": "Currency",
                    "fieldDataType": "StringType",
                    "cntrlFldTypeEnum": "InputField",
                    "operatorEnum": "Equals",
                    "dateTypeEnum": null,
                    "value1TypeEnum": null,
                    "value1": "USD",
                    "value1Set": null,
                    "value1Offset": null,
                    "value2TypeEnum": null,
                    "value2": null,
                    "value2Set": null,
                    "value2Offset": null,
                    "errors": null
                }
            ]
        }
    ],
    "errors": null
}
  constructor(private paymentTableService : PaymentTableService) {

   
    
   }

   onDrop(event: CdkDragDrop<string[]>) {
    this.paymentTableService.paymentTableMetadata
  }
 


  
  ngOnInit() {
   
  }

  
}

and here is my component.html :

<table  >
    <thead>
        <tr *ngIf="this.paymentTableMetadata">
            <th *ngFor = "let paymentCell of this.paymentTableMetadata"> <span >{{paymentCell.cntrlFldLabel}}</span> </th>
            <th > <span >Process Key</span> </th>  
           
          </tr>
    </thead>
    <tbody cdkDropList (cdkDropListDropped)="this.onDrop($event)" id="dataTable" >
        <ng-container  *ngIf="this.paymentTableData.dmnRows.length >0 ; else empty">
            <tr cdkDrag cdkDragLockAxis="y" *ngFor="let tableRow of this.paymentTableData.dmnRows" id="{{ tableRow.rowCode }}"
               >
              
                <td *ngFor = "let cell of tableRow.cells">{{cell.value1}}</td>
                <td >{{tableRow.processKey}}</td>
               
            
            </tr>
        </ng-container> 
         <ng-template #empty>
            <p > No Data In Table</p>
        </ng-template>

    </tbody>
  
</table>

when I run this component the currency value1 gets under header amount along with other problems (result column should be empty and process key should have the value LowPaymentBpm), here is the screenshot :

enter image description here

any ideas on how to deal with this are appreciated.

CodePudding user response:

I recommend that you create a pipe, that takes the array of cells and returns an object, which has the codes as properties.

transform(cells: CellsType[]): Record<string, CellsType> {
  return cells.reduce((acc, curr) => ({ ...acc, [curr.cntrlFldCode]: curr }), {});
}

You then add an ng-container, that transforms those cells. After you don't iterate the cells, you iterate the meta array again to get the required keys, which you can use to query the object from the pipe.

<tr cdkDrag cdkDragLockAxis="y" *ngFor="let tableRow of this.paymentTableData.dmnRows" id="{{ tableRow.rowCode }}">
  <ng-container *ngIf="tableRow.cells | myPipe as cells">        
    <td *ngFor="let paymentCell of this.paymentTableMetadata">{{ cells[paymentCell.cntrlFldCode] }}</td>
  <ng-container>
  <td >{{tableRow.processKey}}</td>       
</tr>
  • Related