How can I debug handlebars in node in VS Code? - node.js

I am trying to render a .hbs file
res.render('./reporting/review_email.hbs', { ..._data, layout: false });
however the .hbs file is not properly rendering because there is a property of the _data object which is either missing or incorrect. I know that this is the case because when I replace _data with a JSON object that is manually populated (as opposed to from the database), the template renders fine.
I am wondering how I could debug the issue in VSCode.
Basically I want to know where the compiler encounters the problem.

Related

How to use template engine without using any controller in standalone NestJS Application?

I'm trying to create telegram chatbot application using nestjs-telegraf
And then I've idea to use template engine like what has been taught from here, to render the reply message for each message has been received.
But, I don't find any way how to do that. All I have got is everyone using #Res res parameter in their method, and then just return res.render(...)
Is there any way to that?
I don't want to manually format the reply message by using ` and using string interpolation.
I think you can use a callback parameter from res.render(), like this:
import { Response } from 'express';
import { Post, Controller, Res } from '#nestjs/common';
#Controller()
export class MyController {
#Get()
root(#Res() response: Response) {
await response.render(
'index',
{ variable: 'My variable' },
function (error, html) {
console.log(html)
}
);
// return any JSON you want
return response.send({message: 'You HTML was proceed'})
}
}
Choose View Engine
First of all, you have to choose a view engine, this will be in charge of rendering the template and doing the necessary interpolation.
You can check these view engines:
Handlebars: https://handlebarsjs.com/
Pug: https://pugjs.org/api/getting-started.html
Configure the app
Then, you have to create a view and public folders, usually this folder is located in the root layer of your project directory.
Then, add in your main.ts the following code
This will tell express where are the views (templates) and the public (Css or Js files, etc.) files located.
Add the setViewEngine method indicating the view engine, in this case is handlebars (hbs).
Create template files
With this configuration you can start creating your templates files, let's see the example on the docs.
He created a file in the views folder called index.hbs and wrote that code, handlebars is basically html and the curly braces indicates that you can put a value on that space.
Render the file
The last thing to do is on your controller, create a Get method, add the render decorator and put the name of the view file, then return an object containing the values that you want to interpolate on the template and handlebars will do the rest.
If you need more info or have some questions you can leave me a comment :)

Rendering Twig template returns "cache is corrupted" and outputs PHP code

I'm attempting to render out a Twig template that has no layout, just a few variables and some loops.
When I call the render() function on Twig, it outputs a block of PHP code for the following class:
php
/** path/to/my/template.html.twig */
class __TwigTemplate_435244378aba3a3f94258b7d2af4d53eb7a41acb741dd3ad0efcac038b621c67 extends Twig_Template
{
// bunch of methods for Twig_Template,
// including the compiled version of my template
}
After this it gives me a stack trace with the following exception:
Failed to load Twig template "path/to/my/template.html.twig", index "": cache is corrupted in "path/to/my/template.html.twig".
I'm not even using a cache with this app currently, though adding a cache doesn't seem to make a different. I'm using Twig like this:
// Factory to return a new Twig environment
$loader = new \Twig_Loader_Filesystem(__DIR__ . '/../../views/');
return new \Twig_Environment($loader);
// My class has $this->twig set to the above object
$this->twig->render('path/to/my/template.html.twig', [
'report' => $report,
'file' => $file
]);
Twig seems to be able to read in my template, as the block of PHP code it outputs in the error has a properly compiled version of the template. Attempting to set a cache directory that is writable still results in the same error.
I'm using Twig 1.34.4 and PHP 5.6.29 under Apache.
EDIT
A bit of success, in a way. It seems that Twig is never evaling the code that it's generating.
I edited the vendor/twig/twig/lib/Twig/Environment.php file and on line 448 added the following:
eval("?><?" . $content);
After that my template renders just fine. That leads me to the conclusion something else in Twig is breaking, but this isn't a long-term solution since I shouldn't be editing the vendor files.
The block starting at line 456 seems to indicate that $content should have the opening <? but mine doesn't. So that could be screwing with the compilation.
Time for more digging.
I finally figured it out. It wasn't Twig's fault.
Our deployment process was leaving old files on the disk, so I was running with only part of 1.34.4 upgraded.
Fixed that and everything works.

Circular dependencies with node modules import using Browserify and React

I just figured out that I have circular dependencies in my modules. (cjsx stands for Coffee+JSX)
I have a file index.cjsxwhich contains the following:
modules =
App: require('./App')
Code: require('../../components/elements/code/Code')
Icon: require('./icon/Icon')
Page: require('./page/Page')
Toolbar: require('./toolbar/Toolbar')
Toolbars: require('./toolbar/Toolbars')
Wysiwyg: require('./wysiwyg/Wysiwyg')
console.log modules
module.exports = modules
Then, on my application, I use the following syntax:
{ Icon, Toolbar, Toolbars } = require '../index'
The index.cjsx is here just to allow this syntax and avoid to require each module separately.
But now I'm facing the issue where my App component requires the index file, and my index file requires App. There is a circular dependency. It's not causing a bug by itself but things get complicated at some point because now, when I require index in some component, I only get an empty object {}.
When I add logs in Wysiwyg, I see the following:
script.js:197 Object {}// The object is empty, console.log require '../index' (in Wysiwyg)
script.js:90 Object {App: Object}// The object is not empty here and contains everything I need. (console.log modules, in index.cjsx)
script.js:209 undefined undefined
script.js:45151 Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `Wysiwyg`.
It looks like my index is actually loaded after it has been required.
I wonder if I can do something to fix this or if I must require each package separately from the component itself. Thanks for input :)
I fixed the issue by not requiring index from the App component (which is the master and is at the root directory. And by not listing the App component in the index file.
you should use index.js file to require only the files in the current folder. this way you avoid circular dependencies if you manage your folders right. In your example, you would add an index.cjsx in the folder toolbar for example with just Toolbar and Toolbars and then to
{ Toolbar, Toolbars } = require './toolbar'
Note: you can omit the index file, it is assumed if you put a folder path

Node Server debugger code behavior changes when debugging

I am debugging a Node Server written in typescript in WebStorm 10.0.4 and when stepping through the code, the code execution path completely changes. A variable assignment appears to break and reference a different (incorrect) object and break my code.
I have a class CustomerRoutes.ts which contains different methods to handle POST requests. I register the endpoint:
app.post('/Contacts', jsonParser, CustomerRoutes.postContact);
CustomerRoutes.postContact is a public static function which is defined as:
public static postContact(request, response) {
if(request.body.$type == 'Person') {
CustomerRoutes.postIndividual(request, response);
} else if(request.body.$type == 'Organization') {
CustomerRoutes.postOrganization(request, response);
}
}
CustomerRoutes.postIndividual and CustomerRoutes.postOrganization are both public static functions as well. So when the server is in non-debug mode the code executes as expected and the branching statements are executed. However when stepping through the code the variable CustomerRoutes global variable gets reassigned to the contents of request within the scope of CustomerRoutes.postContact
As you can see in the Variables window of the debugger the variable CustomerRoutes has been redefined twice to the values of request and response. So now when stepping through the code and the functions postIndividual and postOrganization are called, CustomerRoutes does not contain those function and POST fails with an exception and error 500.
I do not believe this is any sort of race/timing condition so it must be a bug in the debugger environment. My hunch is that the typescript variable mappings are not working correctly with the debugger but I am not certain. Has anyone seen an issue like this or an idea on a fix? I have never seen anything like it. I am happy to post more information as requested.
My hunch is that the typescript variable mappings are not working correctly with the debugger but I am not certain.
TypeScript doesn't have proper variable mapping in sourcemaps at the moment. Follow this issue : https://github.com/Microsoft/TypeScript/issues/2859 (also answered it here once : Chrome Typescript debugging references wrong 'this')
Has anyone seen an issue like this or an idea on a fix?
Disable sourcemaps to see what is actually going on in the raw JavaScript.

Node app variables passed into stylus file

I am building a little node app and using Express with Jade and Stylus to render some basic HTMl pages.
I was curious if there is a way for me to pass some variables INTO the .styl file that are generated from Node? I am well aware that i can define variables inside of the .styl file but I have a need to be more dynamic. Specifically i was looking for an easy way to store some colors in the db, have node grab those values, then insert those into the .styl file so that when the page is rendered these variables are passed in. It seems like this should be do-able but i am lacking on the details. Any help is appreciated. Thanks!
Thanks to #ebohlman as his advice was close to what i ultimately implemented.
basically i was trying to figure out how to do this on top of the Connect Middleware and here is what i came up with:
when doing app.configure i used the custom compile compile function (key 'compile') like so:
app.use(require('stylus')
.middleware({
src: app.root + '/app/public',
compile: compile
})
);
then i created a couple of functions:
var stylus = require('stylus');
var mylib = function(style){
style.define('themeColor1', function(){
//call to the db that returns a color
color = 'blue';
color = color ? color : 'orange';
return new stylus.nodes.Literal(color);
});
};
var compile = function(str, path) {
return stylus(str)
.use(mylib);
};
then inside of the .styl file i do:
background-color themeColor1();
the ternary operator in the themeColor1 function allows for easy defaults and an override. It took me a bit to figure out the API based upon the examples but it seems like this COULD be a solution others would want to know how to do. If anyone has any downfalls of this approach please let me know.
You can use the Stylus API's define() function to set Stylus variables and make JS functions available to it.

Resources