[FIXED] Angular table how to put td based on th?

Issue

I would like to put some data in a table so that each data is correctly aligned with the corresponding <th> i am using ng-zorro table but i think it does not matter since it uses standard html tags.

I have this data that i gather from the server (c# web api) which is like this:

[
   {
      "code":"0001",
      "commissionId":"something",
      "commissionType":0,
      "description":"Some Description",
      "registrationList":[
         {
            "activityCode":"01.6",
            "activityDescription":"Desc1",
            "activityId":"ActivityId1",
            "minuteWorked":120
         }
         // ...
         // could have other data same as above
      ]
   }
   // ...
   // other data same as above
]

On the first array i can have multiple commission, and each commission have multiple elements inside the registrationList.
So that would be an array with multiple elements and each single element having another array (registrationList).

So what i need is to:

  • display on the first column the commission code. The column is fixed. (that i know how to do)
  • display the registration list on the table data. Matching the activityCode that is in the table header (this i do not know how to do)

Here’s the table
Here's the table


What i have done is using *ngIf and *ngFor to loop through the first array and then loop on the registrationList but that does not work.

The <th> is generated looping through an activityList
So i did this in my code:

<thead>
  <tr>
    <th>Commission</th>
    <th *ngFor="let activity of activityList" class="text-center">{{activity.code}}</th>
  </tr>
</thead>

<tbody>
  <tr *ngFor="let data of serverData index as i">
    <td nzLeft>{{data?.code}} - {{data?.description}}</td>
    <ng-container *ngFor="let activity of activityList">
      <ng-container *ngFor="let r of serverData.registrationList">
        <td *ngIf="r.activityCode == activity?.code; else noData">{{data.description}} - {{r.activityCode}}
          <td #noData> no data </td>
      </ng-container>
    </ng-container>
  </tr>
</tbody>

If anyone can guide me through a possible solution here, because somehow the table columns (the data) do not corresponds to the table heads and then the table layout is not correct. Thanks!

Solution

So here is the answer, your problem is not the frontend side. From what i can see you have to already format the data so that the front end will only display it. Let me explain:

  • Usually if you have a backend it’s best practice to leave high demanding task to backend. The front end part (Angular) is only there to display things, sure it can do more but doing an *ngFor like you did is not reasonable.

You can format the data in the backend server like this:

  • create a class that holds the cells
  • create a class that holds a row (wich is a list of cells)
  • finally create a class that holds the entire table (with a thead with one row, and a tbody with a list of rows)

PivotCelViewModel.cs

public class PivotCelViewModel
    {
        public string Content { get; set; }
    }

PivotRowViewModel.cs

public class PivotRowViewModel
    {
        public PivotRowViewModel()
        {
            CellList= new List<PivotCelViewModel>();
        }

        public List<PivotCelViewModel>  CellList { get; set; }
    }

PivotViewModel.cs

 public class PivotViewModel
    {
        public PivotViewModel()
        {
            TBody = new List<PivotRowViewModel>();
        }
        public PivotRowViewModel THead { get; set; }
        public List<PivotRowViewModel> TBody { get; set; }
    }

In PivotRowViewModel.cs i am creating a constructor so that i can instantiate a new list every time. This ensure there is no errors when instantiating a new object of that class.

Then what you would probably do is populate those classes so that in front end you just have to *ngFor over the data withouth the need of specific logic.

Hope that helps cheers!

Answered By – ludovicoilgrande

Answer Checked By – David Marino (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published