new_programmer_22
new_programmer_22

Reputation: 475

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: '[email protected]', value: ['message1', 'message2']}
]

I previously had this working using an object like this

[
{key: '[email protected]', 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        |
|  [email protected]   |       message1      |
|                        |       message2      |
|  [email protected]  |       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

Upvotes: 2

Views: 2560

Answers (2)

nash11
nash11

Reputation: 8650

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>

Upvotes: 1

c__money
c__money

Reputation: 76

You're very close; you should just need another *ngFor directive inside your second tag, like this...

<td>
    <span *ngFor="let val of item.value" style="display:inline-block">
        {{ item.value }}
    <span>
</td>

So your final table looks like...

<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>
            <span *ngFor="let val of item.value" style="display:inline-block">
                 {{ item.value }}
            <span>
        </td>
      </tr>
      <tr></tr>
    </table>
  </body>

Upvotes: 2

Related Questions