HTML table from dictionary and arrays

I am trying to build an HTML table from a dictionary, that has objects with an array property. I hope I am not missing something dumb / easy, I have been trying many different variations. Have read the article difference between HTML and fragment (but honestly probably not catching the subtleties of when a fragment is useful). I found this question and answers that is similar but not quite the collection of collections that I have.

I also don’t know if I am better off with an HTML cell that has embedded code, or a javscript cell that has embedded HTML.

Here is what I have for what I think is the closest attempt.

<table>
  <thead>
    <tr>
      <th>Sample ID</th>
      <th>Dates</th>
    </tr>
  </thead>
  <tbody>
    ${ Object.keys(testResultIdsWithTimestamps).map( sampleId =>
      htl.html`<tr>
        <td>${sampleId}</td>
        <td>${testResultIdsWithTimestamps[sampleId].dates.forEach( d => htl.html`${d}<br/>` )}</td>
      </tr>`
    )}
  </tbody>
</table>

and the output I’m getting: no dates :frowning:

I have also confirmed:

  • the dates property is an array (used Array.IsArray and spit out true in the html table)
  • the values in dates array are valid dates (spit out only the dates property and the array “tostring” renders)
<td>${testResultIdsWithTimestamps[sampleId].dates}</td>

Thank you for any guidance!

You probably want dates.map instead of dates.forEach. forEach invokes the callback without returning a value.

htl.html expects the markup to have one root element, and will add a span if it doesn’t. A document fragment on the other hand acts like a temporary root element that “dissolves” as soon as it gets inserted into a DOM, allowing you to insert multiple elements without an additional wrapper.

1 Like

Doh! Since javascript not my main language I wasn’t groking that difference (forEach vs map). Thank you @mootari for the nudge.

And – ahh, that document fragment info helps a lot.

Got it all working then with this.

<table>
  <thead>
    <tr>
      <th>Sample ID</th>
      <th>Dates</th>
    </tr>
  </thead>
  <tbody>
    ${ Object.keys(testResultIdsWithTimestamps).map( sampleId =>
      htl.html`<tr>
        <td>${sampleId}</td>
        <td>${testResultIdsWithTimestamps[sampleId].dates.map( d => htl.html.fragment`${formatDateTime(d)}<br/>` )}</td>
      </tr>`
    )}
  </tbody>
</table>