i have an array of objects
arr =
[
{
user: '[email protected]',
name: 'b',
surname: 'b',
'29_07_2022': 'YES',
'01_08_2022': 'YES',
'11_11_2022': 'YES'
},
{
user: '[email protected]',
name: 'c',
surname: 'c',
'29_07_2022': 'YES',
'01_08_2022': 'NO',
'11_11_2022': 'NO'
}
]
all the dates and the values are dynamic
my problem is, i don't know how to access the dates without knowing the name of the index
{{#each arr}}
<p> USER {{this.user}} </p> Works
<p> Name {{this.name}} </p> Works
<p> USER {{this.surname}} </p> Works
<p> Date1 {{??????}} </p> ?????
{{/each}}
my view is something like this
<table style="width:100%">
<tr>
<th>USER</th>
<th>NAME</th>
<th>SURNAME</th>
{{#Date}} <th> {{moment Date format="DD/MM/YYYY"}} </th> {{/Date}}
</tr>
{{#each arr}}
<tr>
<th>{{user}}</th>
<th>{{name}}</th>
<th>{{surname}} </th>
maybe another each here
<th>{{???????}}</th>
close that each
</tr>
{{/each}}
</table>
i want to print a table like this one
| USER | NAME | Surname | date 1 | date 2 | date 3 |
| [email protected] | b | b | YES | YES | YES |
| [email protected] | c | c | YES | NO | NO |
CodePudding user response:
If you can have different keys in some objects
const arr = [
{
user: '[email protected]',
name: 'b',
surname: 'b',
'29_07_2022': 'YES',
'01_08_2022': 'YES',
'11_11_2022': 'YES'
},
{
user: '[email protected]',
name: 'c',
surname: 'c',
'29_07_2022': 'YES',
'01_08_2022': 'NO',
'11_11_2022': 'NO',
'11_11_2023': 'NO'
}
]
const keys = [...new Set(arr.flatMap((content) => Object.keys(content)))]
console.log(keys)
I can't test but does something like this works ?
{{#each arr as | user |}}
{{#each ../keys as | key |}}
<p> {{key}} {{lookup user key}} </p>
{{/each}}
{{/each}}
CodePudding user response:
As I see for your comment maybe another each here
the objects can have different times.
In that case, you must handle the dates in another array to iterate them and consult inside if the object has that value equal to YES
.
Handlebars don't have a method to compare values, so you will need to change your object values to true
or false
. Another solution is create a Helper
as is in the next example:
const handlebars = require("handlebars");
const fs = require("fs");
const arr = [
{
user: '[email protected]',
name: 'b',
surname: 'b',
'29_07_2022': 'YES',
'01_08_2022': 'YES',
'11_11_2022': 'YES'
},
{
user: '[email protected]',
name: 'c',
surname: 'c',
'29_07_2022': 'YES',
'01_08_2022': 'NO',
'11_11_2022': 'NO'
},
{
user: '[email protected]',
name: 'd',
surname: 'd',
'11_11_3000': 'YES'
}
];
// Handle your dates keys
const dateHeaders = new Set();
// const data = [];
for (const value of arr) {
// Get only dates of the object
const dates = new Set(Object.keys(value));
dates.delete("user");
dates.delete("name");
dates.delete("surname");
// Concat dates
for (const date of dates) {
dateHeaders.add(date)
}
}
// Create an equal condition to use it
// You can ignore it if change the value 'YES' & 'NO' to true & false
handlebars.registerHelper('equal', function (value, value2) {
return value === value2 ? true : false;
});
// Execute handlebars sending the array and the dateHeaders
const template = handlebars.compile(fs.readFileSync("./template.html", "utf8"));
fs.writeFileSync("./output.html", template({
arr,
dateHeaders,
}));
template.html
<table style="width:100%">
<tr>
<th>USER</th>
<th>NAME</th>
<th>SURNAME</th>
{{#each dateHeaders}}
<th>{{this}}</th>
{{/each}}
</tr>
{{#each arr}}
<tr>
<th>{{user}}</th>
<th>{{name}}</th>
<th>{{surname}}</th>
{{#each ../dateHeaders}}
{{#if (equal (lookup ../this this) "YES")}}
<th>YES</th>
{{else}}
<th>NO</th>
{{/if}}
{{/each}}
</tr>
{{/each}}
</table>
output.html
<table style="width:100%">
<tr>
<th>USER</th>
<th>NAME</th>
<th>SURNAME</th>
<th>29_07_2022</th>
<th>01_08_2022</th>
<th>11_11_2022</th>
<th>11_11_3000</th>
</tr>
<tr>
<th>[email protected]</th>
<th>b</th>
<th>b</th>
<th>YES</th>
<th>YES</th>
<th>YES</th>
<th>NO</th>
</tr>
<tr>
<th>[email protected]</th>
<th>c</th>
<th>c</th>
<th>YES</th>
<th>NO</th>
<th>NO</th>
<th>NO</th>
</tr>
<tr>
<th>[email protected]</th>
<th>d</th>
<th>d</th>
<th>NO</th>
<th>NO</th>
<th>NO</th>
<th>YES</th>
</tr>
</table>
NOTE: If you want the dates in an specific order (actually is FIFO) you must convert dateHeaders to an Array
and apply a sort
.