Scripts not loaded in express application



  • Hi all,

    I have a strange phenomenon in my application.
    The report I'm testing has its template, script etc... in the store. When I run jsreport stand alone, I can run the report from the studio without issues.
    However, when I run my own nodejs (with jsreport integrated through jsreport-express), the script is not loaded.

    This is the setup for running jsreport stand-alone:

    const jsreport = require('jsreport')()
    
    if (process.env.JSREPORT_CLI) {
      // export jsreport instance to make it possible to use jsreport-cli
      module.exports = jsreport
    } else {
      jsreport.init().then(() => {
        // running
      }).catch((e) => {
        // error during startup
        console.error(e.stack)
        process.exit(1)
      })
    }
    

    This is how I load jsreport in my own application:

    'use strict';
    
    const express = require('express');
    
    module.exports = {
      init: function(app) {
        const reportingApp = express();
        app.use('/reporting', reportingApp);
        
        const jsreport = require('jsreport')({
          extensions: {
            express: {app: reportingApp},
    
            authentication: {
              enabled: false,
            },
            authorization: {
              enabled: false,
            },
            cli: {
              enabled: false,
            },
            freeze: {
              enabled: false,
            },
            'html-to-xlsx': {
              enabled: false,
            },
            'import-export': {
              enabled: true,
            },
            jsrender: {
              enabled: false,
            },
            'public-templates': {
              enabled: false,
            },
            'sample-template': {
              enabled: false,
            },
            scheduling: {
              enabled: false,
            },
            scripts: {
              enabled: true,
            },
            studio: {
              enabled: false,
            },
            'version-control': {
              enabled: false,
            },
            xlsx: {
              enabled: false,
            },
          },
          allowLocalFilesAccess: true,
          store: {provider: 'fs'},
          tempDirectory: 'temp',
        });
    
        jsreport.init();
      },
    };
    

    This is the template config file:

    {
        "shortid": "BJrOcAemQ",
        "name": "ScoreExpress",
        "recipe": "chrome-pdf",
        "engine": "handlebars",
        "chrome": {
            "printBackground": false,
            "displayHeaderFooter": false,
            "marginTop": "4.5cm",
            "marginBottom": "1.8cm",
            "format": "A4"
        },
        "modificationDate": {
            "$$date": 1531400580455
        },
        "_id": "sDmgvRcf4JP9VG2l",
        "$entitySet": "templates",
        "data": {
            "shortid": "HJpP-REmX"
        },
        "scripts": [
            {
              "shortid": "ByzE3Ce77"
            }
        ],
        "pdfOperations": [],
        "resources": {
            "items": [
                {
                    "shortid": "HJpP-REmX",
                    "entitySet": "data"
                }
            ]
        }
    }
    

    Any idea what is wrong with my setup?


  • administrators

    hmm i think in this case it will be better that you upload your project in a github repository so i can try it locally and tell you what can be your problem, when doing node integration it is important to see how you actually start the app, so far i just see this module init: function(app) {... which i guess it is required from some entry point of your app, those details are important to know because it affect how jsreport initializes fs-store data directory



  • I have changed the logger settings. Now it turns out that the script is executed, but the result is not as expected.
    This is the script that is used:

    const handlebars = require('handlebars');
    
    handlebars.registerHelper('switch', function(value, options) {
      this._switchValue = value;
      const html = options.fn(this); // Process the body of the switch block
      delete this._switchValue;
      return html;
    });
    
    handlebars.registerHelper('case', function(value, options) {
      if (value === this._switchValue) {
        return options.fn(this);
      }
    });
    

    This the log from the report execution:

    C:\ScoreExpress\scoreexpress-web>npm run start
    
    > ScoreExpress@1.0.0 start C:\ScoreExpress\scoreexpress-web
    > cross-env NODE_ENV=production node server/server.js
    
    2018-07-18T13:41:07.026Z - info: Initializing jsreport@2.1.1 in production mode using configuration file: none
    2018-07-18T13:41:07.034Z - info: Searching for available extensions in C:\ScoreExpress\scoreexpress-web\
    Import config data
    init model queues
    Web server listening at: http://localhost:8080
    Browse your REST API at http://localhost:8080/explorer
    2018-07-18T13:41:12.601Z - info: Extensions location cache contains up to date information, skipping crawling in C:\ScoreExpress\scoreexpress-web\
    2018-07-18T13:41:12.859Z - info: Found 31 extensions
    2018-07-18T13:41:14.729Z - debug: Writing extension locations cache to C:\ScoreExpress\scoreexpress-web\temp\core\locations.json
    2018-07-18T13:41:15.124Z - debug: Discovered 31 extensions
    2018-07-18T13:41:15.231Z - info: Setting process based strategy for rendering. Please visit http://jsreport.net/learn/configuration for information how to get more performance.
    2018-07-18T13:41:15.257Z - info: Using extension handlebars
    2018-07-18T13:41:15.279Z - info: Using extension import-export
    2018-07-18T13:41:15.611Z - info: Using extension templates
    2018-07-18T13:41:15.624Z - debug: Extension jsrender is disabled, skipping
    2018-07-18T13:41:15.624Z - debug: Extension authentication is disabled, skipping
    2018-07-18T13:41:15.624Z - debug: Extension freeze is disabled, skipping
    2018-07-18T13:41:15.625Z - debug: Extension cli is disabled, skipping
    2018-07-18T13:41:15.625Z - info: Using extension express
    2018-07-18T13:41:15.954Z - info: Using extension debug
    2018-07-18T13:41:15.960Z - info: Using extension tags
    2018-07-18T13:41:15.968Z - info: Using extension data
    2018-07-18T13:41:15.978Z - info: Using extension fs-store
    2018-07-18T13:41:16.534Z - info: fs store underlying changes synchronization with studio is disabled
    2018-07-18T13:41:16.536Z - debug: Extension authorization is disabled, skipping
    2018-07-18T13:41:16.537Z - debug: Extension html-to-xlsx is disabled, skipping
    2018-07-18T13:41:16.539Z - info: Using extension child-templates
    2018-07-18T13:41:16.549Z - info: Using extension browser-client
    2018-07-18T13:41:16.558Z - info: Using extension chrome-pdf
    2018-07-18T13:41:16.699Z - info: Using extension pdf-utils
    2018-07-18T13:41:16.891Z - debug: Extension version-control is disabled, skipping
    2018-07-18T13:41:16.892Z - info: Using extension reports
    2018-07-18T13:41:16.896Z - info: Using extension text
    2018-07-18T13:41:16.897Z - info: Using extension base
    2018-07-18T13:41:16.900Z - debug: Extension studio is disabled, skipping
    2018-07-18T13:41:16.900Z - info: Using extension licensing
    2018-07-18T13:41:16.994Z - info: Using extension scripts
    2018-07-18T13:41:17.004Z - info: Using extension assets
    2018-07-18T13:41:17.031Z - debug: Extension scheduling is disabled, skipping
    2018-07-18T13:41:17.031Z - debug: Extension xlsx is disabled, skipping
    2018-07-18T13:41:17.032Z - debug: Extension sample-template is disabled, skipping
    2018-07-18T13:41:17.032Z - info: Using extension resources
    2018-07-18T13:41:17.036Z - debug: Extension public-templates is disabled, skipping
    2018-07-18T13:41:17.043Z - info: fs store is persisting using fs
    2018-07-18T13:41:17.044Z - info: fs store is synchronizing using fs
    2018-07-18T13:41:17.087Z - info: fs store is loading data
    2018-07-18T13:41:17.151Z - info: fs store is initialized successfully
    2018-07-18T13:41:17.181Z - info: Configuring routes for existing express app.
    2018-07-18T13:41:17.189Z - info: Mounting routes under appPath (/reporting).
    2018-07-18T13:41:17.190Z - info: Using existing server instance.
    2018-07-18T13:41:17.191Z - debug: fs store sync modifications is disabled
    2018-07-18T13:41:17.192Z - info: Verifying license key free
    2018-07-18T13:41:17.194Z - info: Using free license
    2018-07-18T13:41:17.195Z - info: reporter initialized
    2018-07-18T13:41:33.142Z - info: Starting rendering request 1 (user: null)
    2018-07-18T13:41:33.249Z - info: Rendering template { name: ScoreExpress, recipe: chrome-pdf, engine: handlebars, preview: false }
    2018-07-18T13:41:33.253Z - debug: Inline data specified.
    2018-07-18T13:41:33.265Z - debug: Executing script ScoreExpress
    2018-07-18T13:41:33.829Z - debug: Replaced assets ["ScoreExpressStyles.css","planned.svg","dns.svg"]
    2018-07-18T13:41:33.838Z - debug: Replaced assets ["Graphik-Medium-Cy-Gr-Web.eot","Graphik-Medium-Cy-Gr-Web.woff","Graphik-Medium-Cy-Gr-Web.woff2","Graphik-Regular-Cy-Gr-Web.eot","Graphik-Regular-Cy-Gr-Web.woff","Graphik-Regular-Cy-Gr-Web.woff2"]
    2018-07-18T13:41:33.841Z - debug: Base url not specified, skipping its injection.
    2018-07-18T13:41:33.843Z - debug: Rendering engine handlebars
    2018-07-18T13:41:34.447Z - warn: Error when processing render request Error while executing templating engine. Missing helper: "switch" Error: Missing helper: "switch"
        at Object.<anonymous> (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\helpers\helper-missing.js:19:13)
        at eval (eval at createFunctionContext (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\compiler\javascript-compiler.js:254:23), <anonymous>:6:95)
        at prog (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\runtime.js:221:12)
        at execIteration (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\helpers\each.js:51:19)
        at Object.<anonymous> (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\helpers\each.js:61:13)
        at eval (eval at createFunctionContext (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\compiler\javascript-compiler.js:254:23), <anonymous>:14:31)
        at prog (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\runtime.js:221:12)
        at execIteration (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\helpers\each.js:51:19)
        at Object.<anonymous> (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\helpers\each.js:61:13)
        at eval (eval at createFunctionContext (C:\ScoreExpress\scoreexpress-web\node_modules\handlebars\dist\cjs\handlebars\compiler\javascript-compiler.js:254:23), <anonymous>:10:31)
    2018-07-18T13:41:34.457Z - warn: Error during processing request at http://localhost:8080/reporting/api/report
    Wed Jul 18 2018 15:41:34 GMT+0200 (Romance Summer Time) | onerrorLogger: {"clientMessage":{"e":{"url":"/reporting/api/report","ok":false,"status":400,"statusText":"Bad Request","headers":{"map":{"strict-transport-security":["max-age=0; includeSubDomains"],"content-encoding":["gzip"],"x-content-type-options":["nosniff"],"x-powered-by":["Express"],"x-download-options":["noopen"],"x-frame-options":["SAMEORIGIN"],"content-type":["application/json; charset=utf-8"],"access-control-allow-origin":["*"],"vary":["Origin, Accept-Encoding"],"date":["Wed, 18 Jul 2018 13:41:34 GMT"],"etag":["W/\"652-xUdbK/t+xjSpCE8yJ+1jKpqtisw\""],"connection":["keep-alive"],"access-control-allow-credentials":["true"],"transfer-encoding":["chunked"],"x-xss-protection":["1; mode=block"]}},"body":{"message":"Error while executing templating engine. Missing helper: \"switch\"","stack":"Error: Missing helper: \"switch\"\n    at Object.<anonymous> (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\helper-missing.js:19:13)\n    at eval (eval at createFunctionContext (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js:254:23), <anonymous>:6:95)\n    at prog (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\runtime.js:221:12)\n    at execIteration (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:51:19)\n    at Object.<anonymous> (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:61:13)\n    at eval (eval at createFunctionContext (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js:254:23), <anonymous>:14:31)\n    at prog (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\runtime.js:221:12)\n    at execIteration (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:51:19)\n    at Object.<anonymous> (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:61:13)\n    at eval (eval at createFunctionContext (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js:254:23), <anonymous>:10:31)"},"bodyBlob":{},"bodyText":{"promise":{}}},"data":{"message":"Error while executing templating engine. Missing helper: \"switch\"","stack":"Error: Missing helper: \"switch\"\n    at Object.<anonymous> (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\helper-missing.js:19:13)\n    at eval (eval at createFunctionContext (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js:254:23), <anonymous>:6:95)\n    at prog (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\runtime.js:221:12)\n    at execIteration (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:51:19)\n    at Object.<anonymous> (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:61:13)\n    at eval (eval at createFunctionContext (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js:254:23), <anonymous>:14:31)\n    at prog (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\runtime.js:221:12)\n    at execIteration (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:51:19)\n    at Object.<anonymous> (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\helpers\\each.js:61:13)\n    at eval (eval at createFunctionContext (C:\\ScoreExpress\\scoreexpress-web\\node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js:254:23), <anonymous>:10:31)"},"logData":{"msg":"unhandledrejection"}},"requestId":"","clientTimestamp":"2018-07-18T13:41:34.484Z"}
    

    Note that the line that says: Executing script ScoreExpress.
    When rendering the report, the switch helper which is registered by the script is not available to the handlebars engine.


  • administrators

    you don't need to register template engine helpers inside a script, helpers are registered along with template in the following section:

    0_1531923980602_Captura de pantalla 2018-07-18 a las 9.25.19 a.m..png

    you can define helpers just by defining functions there, no need to call handlebars manually.

    function switch (value, options) {
      this._switchValue = value;
      const html = options.fn(this); // Process the body of the switch block
      delete this._switchValue;
      return html;
    }
    
    function case (value, options) {
      if (value === this._switchValue) {
        return options.fn(this);
      }
    }
    

    however i'm not sure what your logic is and why you need to save values in this inside a helpers, in most cases helpers functions should be pure. also the names of your helpers looks like they are reserved words (switch, case) in javascript, maybe it will give you problems, so try to change the names if you face some problems



  • Hi Boris,

    Thanks for the answer. Putting the functions in helper.js worked.
    However it is still a mystery to me why it did work before when running stand-alone and not with express.

    The issue with the reserved names only applies when you use the helper names as function names. If you can use the registerHelper function directly, you can use reserved names as helper names. This feels more natural for the template code.
    I would also like to put these helper function in a separate file, to make it easier to reuse them in different templates.

    Using this for keeping the switch value is taken from an example for adding a switch / case construct to handlebars:
    https://github.com/wycats/handlebars.js/issues/927

    Would there be another way to do this?


  • administrators

    However it is still a mystery to me why it did work before when running stand-alone and not with express.

    the same for me, as i say it depends on how the project is organized, so it is difficult to me to guess what was the problem.

    The issue with the reserved names only applies when you use the helper names as function names. If you can use the registerHelper function directly, you can use reserved names as helper names. This feels more natural for the template code.

    good, as long as you don't get a weird error it is fine.

    I would also like to put these helper function in a separate file, to make it easier to reuse them in different templates.

    you can put the functions in an asset and then reference them in the helpers section. you just need to read the docs to know how it works.

    Using this for keeping the switch value is taken from an example for adding a switch / case construct to handlebars:
    https://github.com/wycats/handlebars.js/issues/927
    Would there be another way to do this?

    no clue, i did not dive too depth in the logic, but if it is recommended by another handlebars users i guess you are fine, no need to find other way.


Log in to reply
 

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