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?
-
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.
-
you don't need to register template engine helpers inside a script, helpers are registered along with template in the following section:
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/927Would there be another way to do this?
-
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.