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>
    

  • administrators

    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}}}
    

    https://playground.jsreport.net/w/anon/bpPzfUZ0



  • 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!


Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.