How to use node.js methods in Jade template within Wintersmith - node.js

I have asked google like million times and haven't got any concrete answers... I would like to use, say, following code in the jade template... however it gives an error on the first line... Please could you point me to the right direction... Thanks in advance!!
var fs = require('fs');
fs.unlink('/tmp/hello', function (err) {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});

First, you're missing hyphens to escape your template code to JavaScript. Add a hyphen to each line for starters.
- var something = 0; // example!
Source: Jade reference
Second, #barry-johnson is right to point out your Node code probably belongs somewhere else. It looks like you're trying to clean up a directory during the build. There are other, better ways to accomplish this. I suggest taking a look at the Writing Plugins page for more info.
If that doesn't suit you, please describe in more detail what you're trying to accomplish for better guidance. I hope that helps!

Related

console.log() not appearing in output for express server

I can't for the life of me figure out how to get console.log() to appear with my express server. It's a middle-tier API for our front-end. You'll have to forgive me if I speak about it a little awkwardly, I'm relatively inexperienced with these tools but I'll do my best to explain the issue despite my inexperience. I'm trying to use console.log to get a better idea of a rather complex projects behavior and what might be causing some issues with it in its current state. Unfortunately console.log only seems to work within plainjane examples like so:
export const routerExample = express.Router();
routerExample.use((req, res, next) => {
console.log('Time: ', Date.now()); // I show up in console just fine
next();
});
When I try to lookup the problem I'm experiencing all solutions seem to be regarding getting routing examples like the one above to appear in console, I can see such examples just fine. The problem comes from getting anything to show up in examples like:
// routing.ts
import { homeController } from '../controllers/homeController';
const homeEx: HomeExample = new HomeExample();
routerExample.get('/home', homeEx.getHome);
// homeController.ts
export class HomeExample {
public getHome (req: Request, res: Response) : void {
console.log("something is happening");
// do stuff
}
}
Any uses of console.log like above never appear anywhere in node's console (or elsewhere as far as I can tell).
What am I missing that is needed to make these log messages appear? This has to be incredibly simple but I've been through numerous similar sounding issues on stackoverflow and elsewhere and everything single of one of them seems to be describing slightly different issues (or misunderstandings) that don't solve my own issue. I've tried numerous versions of node/npm and have added the DEBUG:* flag as well. None of this seems to solve it. If I'm missing any code that'd help give context to the issue let me know. I've obviously cut down parts and renamed some objects as I can't exactly dump work-related code here. What am I missing? Any help would be greatly appreciated :)
Edit 1: since many similar posts to this seem to get this mixed up, no I'm not looking at my front-end's console or something for the output. I'm looking in the terminal window where I start the server from, where the router example does appear.
Edit 2: for reference, my file structure is something like:
app/
controllers/
homeController.ts (HomeExample stuff is here)
routes
routing.ts (routerExample stuff is here)
app.ts
...
Edit 3: the code works overall to be clear. the problem is explicitly that that log.console() isn't appearing, all the code I've wrapped into "// do stuff" is working as expected.
Checkout Express Middlewares
routerExample.get('/home', homeExample);
function homeExample (req: Request, res: Response, next:NextFunction) : void {
console.log("something is happening");
// do stuff
}
}
You are also calling a member of a non static or instantiated class see this:
TypeScript - Static
What you are missing is to create a new instance of the homeExample class. What I recommend is to export the new instance on the route file like this:
/routes/home.route.js
class HomeRoute {
/* your methods */
}
export default new HomeRoute();
then you can use it:
import homeRoutes from './routes/home.route';
router.get('/home', homeRoutes.getHome);
See the example:
https://replit.com/#abranhe/expressjs-console-log#index.js
After a fresh nights sleep I've figured it out. It, of course, was the most obvious problem that managed to slip by me in the overall complexity of the codebase. The /home call was deprecated and replaced with a different call in the front-end without mention in the middle-tier code that I had posted. I didn't even consider checking what was being called any deeper since I was experiencing the same issue with multiple other calls that I didn't include in the original post for brevity. Basically all the tools I'm working with here are completely new to me so my inexperience got the best of me. Thank you to #jfriend00 who made me double-take how /home was being called (it wasn't).
Since I was getting the data I needed without issue on the front-end I assumed these functions were being run, seeing as the data they produced was the same kind of data that was successfully being shown by the front-end, just without the console.log() output I added appearing.
Moral of the story: if every other question related to an issue on Stack Overflow concludes with "I just made a dumb mistake," take absolutely every precaution possible to observe what's happening, even if you feel like you already ruled out certain possibilities. Unfortunately I got a bit caught up with all the weird solutions I saw to the point where I got ahead of myself in debugging the problem.
I'm still a bit confused since the /home call specifically should still be "active" even if not called by the front-end, but console.log() is clearly working on other similar functions I've tested since figuring this out. There's either something hidden deep in the codebase that's breaking/overwriting /home and other old calls, or it's simply not being called right when I'm testing it outside of the front-end.
TLDR: I'm an idiot, every single API call I thought I was testing was not actually being called. Double-check your assumptions before asking for a specific solution.

How can I split my code, and keep it all asynchronous?

I've been coding just as a side project for a bit, piecing together bits that other people have written (it's for a simple discord bot). I want to split my code to make it easier to problem solve and read, however whenever I try to use the code it comes up with an error saying 'SyntaxError: await is only valid in async function'.
I've tried supposedly loading the code asynchronously, loading it with require() and then making a single command asynchronous, making the entire code in the file asynchronous (it's not just one command I want to load, but a whole file. Also I'm not sure if I tried it correctly or not), using the npm async-require, and maybe some others that have been around on the internet.
//one of the solutions I've tried. This is just copy pasted from the
//answer
//file2.js
var fs = require('fs');
module.exports = function (callback) {
fs.readFile('/etc/passwd', function (err, data) {
callback(err, data);
});
};
//file1.js
require('./passwords')(function (err, passwords) {
// This code runs once the passwords have been loaded.
});
In the first file before I split it, I started it with client.on('message', async message => { and it made me able to use the await function in every command. I want to still be able to do that, but just have it a bit neater and easier to use by splitting it.
I'm trying to get this done so I can move on to a different question I asked and give one of the answers a tick. Any help would be greatly appreciated <3
Fix those awaits so that they are not inside async functions. This is a lexical issue that can be solved just by looking at the location were the error occurs. Just look for the nearest containing function to where the await is and mark it async. Repeat until the error goes away.

Node.js learning guide or study plan

I am a PHP developer trying her hands on node.js. The introductory books about it and online tutorials are great and are helping me come to speed with this language
however I find the official site nodejs.org documentation hard to drill through for somewhat reasons I don't understand, may be I am just spoiled by php.net.
For example many asynchronous functions take a callback function with arguments and docs document that fact but the types of arguments these callbacks take are barely (not) documented
See below
fs.readFile('./template.html', function(err, data) {
if (err) {
console.error(err);
res.end('Server Error');
}
else {
var tmpl = data.toString();
}
});
Here the data argument appears to be an object with toString method and that's all I know about it.
Old langange users can you please point or guide me on how to get the most out of this nice langange, it can be anything such as how to read the docs.
Thank you.
The docs for node.js seem clear to me.
The callback is passed two arguments (err, data), where data is the contents of the file.

Breaking up node module code (for a library/api client)

I'm writing a node module to consume a REST API for a service. For all intents and purposes we might as well say it's twitter (though it's not).
The API is not small. Over a dozen endpoints. Given that I want to offer convenience methods for each of the endpoints I need to split up the code over multiple files. One file would be far too large.
Right now I am testing the pattern I will outline below, but would appreciate any advice as to other means by which I might break up this code. My goal essentially is to extend the prototype of a single object, but do so using multiple files.
Here's the "model" I'm using so far, but don't think is really a good idea:
TwitterClient.js
function TwitterClient(){
this.foo = "bar";
}
require("fs").readdirSync("./endpoints").forEach(function(file) {
require("./endpoints/" + file)(TwitterClient);
});
var exports = module.exports = TwitterClient;
endpoints/endpointA.js etc
module.exports = function(TwitterClient){
TwitterClient.prototype.someMethod = function(){
//do things here
}
}
The basic idea obviously is that any file in the endpoints folder is automatically loaded and the TwitterClient is passed in to it, so that it's prototype can be accessed/extended.
I don't plan to stick with this pattern because for some reason it seems like a bad idea to me.
Any suggestions of better patterns are very much appreciated, cheers

Node.js and Express - Regarding rendering pages in a directory with one call

Hopefully I'm not duplicating a question here, but I looked around and didn't see anything that addressed this specific issue.
I'm constructing some pages by creating a bunch of unique content blocks that I store in a folder - things like this:
h4 Content Example
p.description.
Lorem ipsum dolor sample text etc etc
in, say, pages\contentBlocks\Example\contentExample.jade.
These content blocks are added to a mixin (pages\mixins.jade) that looks like this:
mixin contentBlock(title)
.content-block(id=title.toLowerCase())
h3 #{title}
if block
.content
block
and I call this mixin within a larger page (pages\portfolio.jade) like this:
.subsection
//- Expects a list of objects of the format { title, html }
each val in pageBlocks
+contentBlock(val.title)
!= val.html
(the intention is to later enhance this with other variables that can be passed down into the mixin for in-place formatting, like background images)
I would like to make use of the ability of Express to automatically render all of the pages in a directory in a single call. Like so (index.js):
var pageBlocks = [];
res.render('pages/contentBlocks/Example/*', function (err, html) {
if (err) throw err;
pageBlocks.push({ html: html });
});
However, I'd also like to be able to reference the title of the file, for example for setting the class of the block that I put it in. Ideally, it would look something like this:
res.render('pages/contentBlocks/Example/*', function (err, html) {
if (err) throw err;
pageBlocks.push({ title:functionToGetFileName(), html: html });
});
Is there any way to do this without manually iterating through the files in that directory?
Or, since this method seems needlessly convoluted (given the presence of mixins, includes, extends, and partials, it feels like I ought to be able to do this without extra render calls), is there a better way to do this?
Edit: I've done a bit more looking around and code testing, and now I'm unsure. Can Express implicitly render all of the files in a directory? Based on this question, I assumed it could, but I might have misread. The formatting of res.render('path/to/directory/', callback) doesn't seem to be working - I get the following error:
Error: Failed to lookup view "path/to/directory/" in views directory "/path/to/app/views"
For a temporary solution, I am using the following pattern:
exampleBlocks = [];
eb_dir = "pages/contentBlocks/Example";
fs.readdirSync("./views/" + eb_dir).forEach(function(file) {
res.render(eb_dir + "/" + file, function (err, html) {
if (err) throw err;
exampleBlocks.push({title: file, html:html})
});
});
Which is concise enough for my tastes, though calling res.render() so many times rustles my jimmies. I'd rather it be a single batch render, or better yet, solved through clever use of jade structures - but I still haven't thought of a way to do the latter.
Edit:
I decided I'd rather not simply enumerate the files in the folder - I want more control of the order. Instead of using an each loop in my page, I'm simply going to call the mixin with included content, like this (pages\portfolio.jade in my previous examples):
.subsection
+contentBlock("Block 1")
include blocks/block1
+contentBlock("Block 2")
include blocks/block2
I will leave the question here, however, as others may encounter a similar issue.

Resources