Using handlebars {{each}} helper to populate a javascript variable array
-
Hi,
This might be a bit silly since I'm a bit bit new with JSReport, but I'm trying to do something like this to iterate over my data source and compile with the
{{#each}}
helper in the template where I have an inline<script>
I'm using for a chart. At the moment, this doesn't seem to be working:const chartData = [ {{#each MXEvents}} { date: "{{this.date}}", {{#each this.part}} partName: {{this.partName}}, totalEventsCost: {{this.totalEventsCost}} {{/each}} }, {{/each}} ]
The above
{{each}}
theoretically should work, because if I do the same in the template, like this, it populates it perfectly:<ul> {{#each MXEvents }} <li>{{this.date}}</li> <ul> {{#each this.part}} <li>{{this.partName}} - {{this.totalEventsCost}}</li> <ul> {{#each this.event}} <li>{{ this.eventName }}</li> {{/each}} </ul> {{/each}} </ul> {{/each}} </ul>
I'm not sure if I'm doing it right or if there is a better way to do this. In essence, what I'm trying to achieve is to bring this data into the javascript, so I can loop it through and populate it for a Highcharts.js code.
Any help pointing me in the right direction will be highly appreciated 🙏. Not sure if it'll be of any use, but here is the full code I'm using.
//<!-- chart container. --> <div id="mx_events_chart" class="mb-4"></div> <script> // Extract the data and prepare the series for Highcharts const chartData = [ {{#each MXEvents}} { date: "{{this.date}}", {{#each this.part}} partName: {{this.partName}}, totalEventsCost: {{this.totalEventsCost}} {{/each}} }, {{/each}} ] // console.log(chartData); //const testing = document.getElementById('testing'); //testing.textContent = JSON.stringify(chartData); // Extract unique dates and partNames const uniqueDates = []; const uniquePartNames = []; chartData.forEach(({ date, partName }) => { if (!uniqueDates.includes(date)) { uniqueDates.push(date); } if (!uniquePartNames.includes(partName)) { uniquePartNames.push(partName); } }); // Create an object to store series data based on partName const seriesData = {}; // Initialize seriesData with zero values for each date uniquePartNames.forEach((partName) => { seriesData[partName] = { name: partName, data: uniqueDates.map((date) => { const dataPoint = chartData.find((data) => data.date === date && data.partName === partName); return dataPoint ? dataPoint.totalEventsCost : 0; }), }; }); // Convert seriesData object into an array of series const chartSeries = Object.values(seriesData); // Create the Highcharts chart Highcharts.chart('mx_events_chart', { chart: { type: 'column', }, title: { text: '', }, yAxis: { title: { text: '' } }, xAxis: { categories: uniqueDates, }, credits: { enabled: false, }, plotOptions: { column: { stacking: 'normal' }, series: { animation: false, }, }, series: chartSeries, }); </script>
-
i think you can use the toJS helper to format your data into content that can be used as a javascript variable
const chartData = {{{toJS MXEvents}}}
-
Ahh brilliant! I think I'm getting somewhere with your pointer. Thanks a mill @bjrmatos ! I'll report back, how it goes.
-
Ok, this worked.
const mxEventsData = {{{toJS MXEvents}}}; const chartData = []; mxEventsData.forEach((event) => { event.part.forEach(({ partName, totalEventsCost }) => { chartData.push({ date: event.date, totalEventsCost: Number(totalEventsCost.replace(/\D/g, '')), // Format to numeric value partName, }); }); });
Thanks a million, once again!