Unable to import handlebar file in nodejs - node.js

I am unable to import handlebars file in nodejs. Although it is importing the file but not compiling properly with given data.
here is my test.handlebars file code
<div>Hey {{firstname}} {{lastname}}</div>
and this is my index.js file code
const Handlebars = require("handlebars");
const testEmailTemplate = require("./email-templates/test.handlebars")
const template = Handlebars.compile(testEmailTemplate());
console.log(template({ firstname: "Nils", lastname: "Test" }));
And I am getting below output in console
<div>Hey</div>
expected output
<div>Hey Nils Test</div>
Note: - I don't want to use express-handlebar so please suggest some solution only with handlebars.

The require() method expects to get a Node.js module. But in your case, the target file is HTML, and you need to get the content of the file as plain text to use it further. Use for that fs module and it's method fs.readFile() or fs.readFileSync()
The result code should look like:
const fs = require("fs");
const Handlebars = require("handlebars");
const testEmailTemplate = fs.readFileSync("./email-templates/test.handlebars", "utf-8")
const template = Handlebars.compile(testEmailTemplate);
console.log(template({ firstname: "Nils", lastname: "Test" }));
Info: What is require?

Related

How can i transpile a jsx file imported dynamically in nodejs?

I am currently working on a nodejs command-line package that should dynamically import a React component basing on the path of the component passed as parameter. My code is the following:
const path = require('path')
const pathArg = process.argv[2]
const componentPath = path.join(filePath, '../../../', pathArg)
const {default} = await import(componentPath)
The component i want to import would be something like
// src/components/Button/index.jsx
function Button () {
return <button>Click me!</button>
}
module.exports = Button
However, when i run my script passing src/components/Button/index.jsx as param, i receive unexpected token "<" while reading <button>, since the file is in jsx.
How can i transpile the React file dynamically (e.g. with Babel) and get rid of the error?

XML scraping using nodeJs

I have a very huge xml file that I got by exporting all the data from tally, I am trying to use web scraping to get elements out of my code using cheerio, but I am having trouble with the formatting or something similar. Reading it with fs.readFileSync() works fine and the console.log shows complete xml file but when I write the file using the fs.writeFileSync it makes it look like this:
And my web scraping code outputs empty file:
const cheerio = require('cheerio');
const fs = require ('fs');
var xml = fs.readFileSync('Master.xml','utf8');
const htmlC = cheerio.load(xml);
var list = [];
list = htmlC('ENVELOPE').find('BODY>TALLYMESSAGE>STOCKITEM>LANGUAGENAME.LIST>NAME.LIST>NAME').each(function (index, element) {
list.push(htmlC(element).attr('data-prefix'));
})
console.log(list)
fs.writeFileSync("data.html",list,()=>{})
You might try checking to make sure that Cheerio isn't decoding all the HTML entities. Change:
const htmlC = cheerio.load(xml);
to:
const htmlC = cheerio.load(xml, { decodeEntities: false });

React gives Error: not supported error when I try and import local module

I have a local module (speech.js) in my create-react-app src folder that is the google text to speech code on their website. I adjusted it to be an arrow function and use that specific export syntax.
const textToSpeech = require('#google-cloud/text-to-speech');
// Import other required libraries
const fs = require('fs');
const util = require('util');
export const main = async () => {
// Creates a client
const client = new textToSpeech.TextToSpeechClient();
// The text to synthesize
const text = "Hello world";
// Construct the request
const request = {
input: {text: text},
// Select the language and SSML Voice Gender (optional)
voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
// Select the type of audio encoding
audioConfig: {audioEncoding: 'MP3'},
};
// Performs the Text-to-Speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);
await writeFile('output.mp3', response.audioContent, 'binary');
console.log('Audio content written to file: output.mp3');
};
What I'm not understanding is why this syntax isn't working in App.js.
import {main} from './speech';
I get the error, Error: not support and "4 stack frames were collapsed". Quite informative!
Does anyone know what the error could be here? I thought as long as I used es6 style imports and exports I wouldn't receive errors. Could this be due to the first require() statement of speech.js? Any help would be appreciated. I've felt like banging my head against the wall for the past 40 minutes.
May not be the correct answer but I believe it has a good chance of being right. I believe that since node is just a runtime environment and not a part of the actual browser, you aren't able to use node modules with react (a frontend framework). The solution to this quandary would be to use something like electron.

How to dynamically import data in a nodejs app?

I would like to use require in a node/express app with typescript to import a json. I tried it like this:
const url = `./data/${resource}.json`;
const data = require(url);
but I get the error Cannot find module './data/my-data.json'.
I'd like to use require instead of an import in order to create the data variable dynamically depending on the value of the resource variable.
const path = require('path');
const url = path.resolve(__dirname, `./data/${resource}.json`);
const data = require(url);
The require keyword is a special keyword in nodejs. It is used to load modules, and since your json file is not a module, hence the error. Try this, this way you can dynamically load your json.
import fs from 'fs';
const file = fs.readFileSync(`./data/${resource}.json`).toString();
const data = JSON.parse(file);
There may be better ways to write this function, read mode about the fs module here.
Edit: As someone had alredy pointed out, it is actually possible to dynamicallyrequire json file. Here's how,
import path from 'path';
const uri = path.resolve(__dirname, `<path_to_json_file>`);
const data = require(uri);
However, as a standard practice, use the fs module to load static assets to your project.
import fs from 'fs';
const file = fs.readFileSync(`./data/${resource}.json`).toString();
const data = JSON.parse(file);

How to pass PDFKit readable stream into request's post method?

My app needs to create a PDF file and then upload it to another server. The upload happens down the line via the post method from the request NPM package. Everything works fine if I pass in an fs.createReadStream:
const fs = require('fs');
const params = {file: fs.createReadStream('test.pdf')};
api.uploadFile(params);
Since PDFKit instantiates a read stream as well, I'm trying to pass that directly into the post params like this:
const PDFDocument = require('pdfkit');
const doc = new PDFDocument();
doc.text('steam test');
doc.end();
const params = {file: doc};
api.uploadFile(params);
However, this produces an error:
TypeError: Path must be a string. Received [Function]
If I look at PDFKit source code I see (in coffeescript):
class PDFDocument extends stream.Readable
I'm new to streams and it's clear I'm not understanding the difference here. To me if they are both readable streams, they should both be able to be passed in the same way.

Resources