ES6 problem in 2.1.1 handlebar helper that worked fine in 1.8.2



  • I have a handlebar helper function:

    function SummarysForContact(map, name) { 
        var summary = "";  
        var byname = map.get(name);
        byname.forEach(function(val, key) {
            summary += '<h4>Trouble # ' + key.toString() + " - " + val.Minutes + " minutes </h4>\r\n";
            summary += "<div>\r\n";
            summary += val.Summary.replace(/(?:\r\n|\r|\n)/g, '<br />');
            summary += "</div>\r\n<hr/>";
        });
    
        return summary;
    }
    

    The first parameter is an ES6 Map - works fine in 1.8.2 .NET embedded - does not work in 2.1.1 native node version. Give this following error:

    Error while executing templating engine. map.get is not a function. Error on line 3:22.
    
      1 | function SummarysForContact(map, name) { 
      2 |     var summary = "";  
    > 3 |     var byname = map.get(name);
        |                      ^
      4 |     byname.forEach(function(val, key) {
      5 |         summary += '<h4>Trouble # ' + key.toString() + " - " + val.Minutes + " minutes </h4>\r\n";
      6 |         summary += "<div>\r\n";
    


  • Try to print out what is the map parameter.
    How do you pass it to the helper function?

    There should me no change regarding this in v1.8.2 => v2.1.1



  • The simplest template/script/helper I could make to reproduce:

    <html>
    <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="https://cdn.rawgit.com/olton/Metro-UI-CSS/master/build/css/metro.min.css">
    </head>
    <body>

    <!--{{Summarys}}-->
    {{#each Contacts}}
    <h4 style='page-break-before: always;'>{{ContactName}} - {{NumMinutes}} minutes on {{NumTickets}} tickets</h4>
    {{{SummarysForContact ../Summarys ContactName}}}
    {{/each}}    
    

    </body>
    </html>

    function SummarysForContact(map, name) {
    var summary = "";

    summary += `<p>map = ${map}, name = ${name}</p>`;
    /*
    var byname = map.get(name);
    byname.forEach(function(val, key) {
        summary += `<p>key = ${key}, val = ${val}</p>`;
    });
    */
    
    return summary;
    

    }

    function beforeRender(req, res, done) {
    req.data.Contacts = [{ ContactName: "User1", NumMinutes: 100, NumTickets: 11}, { ContactName: "User2", NumMinutes: 200, NumTickets: 21 }];
    req.data.Summarys = new Map();

    var submap1 = new Map();  
    submap1.set(11, "description for 11"); 
    submap1.set(12, "description for 12");
    req.data.Summarys.set("User1", submap1);
    
    var submap2 = new Map();
    submap2.set(21, "description for 21"); 
    submap2.set(22, "descripton for 22");
    req.data.Summarys.set("User2", submap2);
    
    done();
    

    }



  • The default config file sets up jsreport to evaluate templating engines in extra process. This means we serialize and deserialize data when running stcript or templating engine. This means we loose types like map in this process.

    To make your code working you can configure jsreport to run scripts and templating engines in the same process as the whole application.

    {
    "templatingEngines": {
        "timeout": 10000,
        "strategy": "in-process"
      }
    }
    

    Another option is to avoid using extra types like Map which cannot be simply serialized/deserialized.
    In this case you can probably use simple plain object.



  • Thanks for following up on this - sure enough using plain old object fixed it! I think i used map originally just to see if newer ES5/6 stuff worked which i guess it does minus this serialization issue.


Log in to reply
 

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