Search code examples
javascripthtmlangularngfornested-table

How could I use ngFor to design this (maybe nested) table


I have an Object Array that has a key and then has an array for it's value. Something like this:

[
{key: 'example@example.com', value: ['message1', 'message2']}
]

I previously had this working using an object like this

[
{key: 'example@example.com', value: 'message'}
]

but I would like to change the functionality some so I switched to the value being an array instead.

I want to create a table that looks something like this

|       User Email       |       Result        |
|  example@example.com   |       message1      |
|                        |       message2      |
|  example1@example.com  |       message1      |
|                        |       message2      |

It can be a nested table or it can just show the two messages in the table cell. I am not too picky.

I tried nesting the table, but that did not work. I am not sure how I can use a second ngFor to do something like this.

This is my html that works with the Object Array that does not have an array for its value

<div class="container" style="text-align:center">
  <br />
  <h1>Results</h1>

  <head>
    <style>
      table,
      th,
      td {
        border: 1px solid black;
        align: center;
      }
    </style>
  </head>
  <body>
    <table style="width:50%" align="center">
      <tr>
        <th *ngFor="let col of displayedColumns">
          {{ col }}
        </th>
      </tr>
      <tr *ngFor="let item of userResults | keyvalue">
        <td>{{ item.key }}</td>
        <td>{{ item.value }}</td>
      </tr>

      <tr></tr>
    </table>
  </body>

I tried changing the item.value line with another table and another ngFor, but nothing printed.

any ideas would be appreciated


Solution

  • You do not need to use the keyvalue pipe. The keyvalue pipe is used to transform an object into an array of key value pairs so using this will give you incorrect values in your table. On the other hand, you have a normal array of objects with one property that contains an array. This format is perfect for a nested ngFor.

    Change your table to the code below

    <table style="width:50%" align="center">
      <tr>
        <th *ngFor="let col of displayedColumns">
          {{ col }}
        </th>
      </tr>
      <tr *ngFor="let item of userResults">
        <td>{{ item.key }}</td>
        <td>
          <div *ngFor="let value of item.value">
           {{ value }}
          </div>
        </td>
      </tr>
      <tr>
    </table>
    

    In your css add a vertical-align to keep the data in the cell on top.

    table,
    th,
    td {
      border: 1px solid black;
      align: center;
      vertical-align: top;
    }
    

    Here is a working example on stackblitz

    Edit: As requested in the comments, to add html content, use innerHTML on the div like below

    <div *ngFor="let value of item.value" [innerHTML]="value">
    </div>