custom module not defined in nodejs express app - node.js

we made a custom module for express app but getting this error somename is not defined
here is our code
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var somename = require('./somename/common');
// console.log(wahapar.ucfirst("d"));
var routes = require('./routes/index');
var users = require('./routes/users');
common.js
module.exports = {
ucfirst: function(str){
// discuss at: http://phpjs.org/functions/ucfirst/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Onno Marsman
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: ucfirst('kevin van zonneveld');
// returns 1: 'Kevin van zonneveld'
str += '';
var f = str.charAt(0).toUpperCase();
return f + str.substr(1);
},
};
ejs view
<%= somename.ucfirst("this is a string") %>
while console.log(somename.ucfirst("d")); is showing output in the terminal

You should pass your module as a local variable into express app.
app.locals.somename = require('./somename/common');
Then you will be able to use inside ejs templates.
From the express docs app.locals
The app.locals object is a JavaScript object, and its properties are
local variables within the application.
Once set, the value of app.locals properties persist throughout the
life of the application, in contrast with res.locals properties that
are valid only for the lifetime of the request.
You can access local variables in templates rendered within the
application. This is useful for providing helper functions to
templates, as well as app-level data. Locals are available in
middleware via req.app.locals

Related

Instantiating express

I have an issue where I need to load express like this:
var express = require('express');
var app = express();
In order to get .static to work:
app.use(express.static(__dirname+'views'));
Any reason why I can't use shorthand:
var app = require('express')();
When I try the short hand it says express.static is undefined and my script won't run. Is this just a feature that's not supported by express?
Any reason why I can't use shorthand:
var app = require('express')();
If you considered this statement from your script,
app.use(express.static(__dirname+'views'));
you are using static method of express.In order to use this method,you must import express first and store it in some variables like u did
var express = require('express');
From express#express.js
exports.static = require('serve-static');
static defined at class level.
then instantiate it
like this
var app = express();
to get the access to object level(prototype) method and properties like
app#use app#engine etc.
From express#application //line no 78
EDIT :
but then why can't I use app.static if I did var app = require('express')();
As I said,.static is the class level method and not the instance/object(prototype) level.
So,by var app = require('express')()
you will get express instance / object (prototype) which dont have app.static method.So,you can't use.
Read more javascript-class-method-vs-class-prototype-method
This will work: const app = (() => require('express'))()();
But you still need express itself, so there literally is no real point to requiring twice.

Express js modular REST framework

I am planning to develop only rest api using express js, I looked into lot of boilerplate projects. None of them provide modularity. Modularity I mean all code related to articles module need to be in article folder then I can drag and drop that.
I saw MEAN somewhat close to that but it has client side (angular related) code in that. I need pure rest api framework.
To me it doesn't sound like you want to use a MEN stack, I do not see a reason to use MongoDB in your question. You can write modular express apps e.g. like this:
Assuming you have three modules in three different folders moduleA, moduleB and moduleC. Each folder contains its respective logic and provides some RESTful routes to the outside world. In express you would create one separate Router for each module like this:
ModuleA:
/* moduleA/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleA
module.exports = router;
ModuleB:
/* moduleB/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleB
module.exports = router;
ModuleC:
/* moduleC/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleC
module.exports = router;
And then you would have one main app.js file in your root folder where you enable and disble the single modules by mounting them into the main express app:
/* app.js */
var express = require('express');
var moduleA = require('./moduleA/routes');
var moduleB = require('./moduleB/routes');
var moduleC = require('./moduleC/routes');
var app = express();
... // add your main app's middlewares
app.use('/moduleA', moduleA);
app.use('/moduleB', moduleB);
// app.use('/moduleC', moduleC);
app.listen(3000);
In this example the modules moduleA and moduleB are enabled and are reached by the routes /moduleA/* and /moduleB/* respectively. The module moduleC is disabled as we commented it out.
If you have questions please leave a comment.
It sounds like you want to use a "MEN" stack, which is MongoDB (for backend), Express, and Node.JS.
Here's a tutorial on how to build a project with a "MEN" stack: https://github.com/maslennikov/node-tutorial-men or this one: https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

npm debug can i invoke with multiple names

Currently I am initializing the debug module by
import express = require('express');
import debug = require('debug');
var routeLogger = debug('myapp:routes:index');
var router = express.Router();
routeLogger('Start setting up index route');
I am wondering if i can put more than one name to the debug function? such as debug('myapp,routes,indexRoute')

Can I pass variable to required file?

In express, I'm trying to move my minification to a requierd file:
app.js:
var app = express();
var minify = require("./minify.js");
In that file I try to set my template engine.
minify.js:
var app = express();
app.engine('html', mustacheExpress());
Later when I try to use to use the rendering engine in app.js, I get the error that no template-engine is set. It works if I run it all in the same file. I think the problem is that I declare the app-variable twice. How can I pass the app-variable into minify.js?
The problem is that you define new app variable, and you currently instantiate brand new express instance by calling express().
What you need to do is start using functions so that you can pass params (there are other methods too, but this is one that will work for you):
// app.js
var app = express();
var minify = require('./minify'); // don't include .js!
minify(app); // CALL the function that minify.js exports, passing params
// minify.js
module.exports = function(app) {
// because app comes as a parameter, it's the very same you've created in app.js
app.engine('html', mustacheExpress());
}
Again, there are many different methods and maybe proper approaches, depending on what you want to do, but this will do the job in your case. Read more about NodeJS and it's require system.
You can pass 'app' from app.js to your minify by using function in your module like Andrey said. You can do it like this too for example :
minify.js
module.exports = {
setAppEngine : function(app) {
app.engine( [...] );
}
}
And calling it like this in your app.js:
app.js
var app = express();
var minify = require("./minify.js").setAppEngine(app);
This solution is very useful because you can set and call others methods in minify.js. For example, you can do with the same code in minify.js:
app.js
var app = express();
var minify = require("./minify.js");
minify.setAppEngine(app);

Two way communication between routers within express app

I have an express app that has a router for different sections of my application, each contained within individual files. At the end of each file I export the router object like so.
var express = require("express");
var router = express.Router();
//routing handlers
module.exports = router;
However my problem is that I am trying to implement a feature were a user is allowed to edit a post that could be displayed on the front page, therefore in order to have the most current version of the user's post I need to be able to know when the user edits the post to make the necessary changes.
I have two modules one that handles dispatching the user's posts call this module B and another that handles editing call this module A. I need to be able to have module A include handler function and an array from module B, but I also need module B to be able to be notified when to make changes to the its array that module A requires.
I have tried
module A
var express = require('express');
var EventEmitter = require('events').EventEmitter;
var evt = new EventEmitter();
var router = express.Router();
var modB = require('moduleB');
router.evt = evt;
module.exports = router;
Module B
var express = require('express');
var router = express.Router();
var modA = require('moduleA').evt;
modA.on('myEvent',handler);
var myArray = [....];
router.myArray = myArray;
module.exports = router;
This gives me an undefined for modA and throws an error. I suspect it might be the order the modules are included but anyhow I would like to obtain some feedback since I sense that this might not even be good practice.
I think you are running into a common scenario for someone just starting out with express. A lot of people stick everything into routes/controllers when really the route should be very simple and just extract the data needed to figure out what the request is doing and then pass it to a service for most of the processing.
The solution is to create a Service and put the bulk of your logic and common code there, then you can wire up ModA and ModB to use the Service as needed.
EDIT with an example(not working but should give you a good starting point):
Shared Service
var EventEmitter = require('events').EventEmitter;
var evt = new EventEmitter();
module.exports = {
saveData: function(data) {
// do some saving stuff then trigger the event
evt.emit('myEvent', data);
},
onDataChange: function(handler) {
evt.on('myEvent', handler);
}
};
Module A
var service = require('SharedService.js');
// listen for events
service.onDataChange(function(e, data) {
// do something with the data
});
Module B
var service = require('SharedService.js');
// save some data which will cause Module A's listener to fire
service.saveData(data);
This example above hides the implementation of EventEmitter which may or may not be desirable. Another way you could do it would be to have SharedService extend EventEmitter, then your Modules could listen/emit directly on the service.

Resources