I am using node.js (v4.2.2) with express (4.13.1). I am trying to import my custom module functions to another module. Application is created with express, and only thing added to app.js is require for my route var tests = require('./routes/tests'); and app.use for that route app.use('/tests', tests);
My two custom files (modules) are (path is relative to project root):
./model/test.js
./routes/tests.js
Here is ./model/test.js:
var id;
var testNumber1;
var testNumber2;
function Test(id, testNumber1, testNumber2) {
this.id = id;
this.testNumber1 = testNumber1;
this.testNumber2 = testNumber2;
};
exports.reset = function() {
this.testNumber1 = 0;
this.testNumber2 = 0;
};
module.exports = Test;
And here is ./routes/tests.js:
var express = require('express');
var Red = require('../model/test.js');
var router = express.Router();
/*create new test :id*/
router.post('/:id', function(req, res, next) {
var myNewTest = new Red(req.params.id, 0, 0)
myNewTest.testNumber2 += 1;
myNewTest.reset();
res.send('id: ' + myNewTest.id +
' testNumber2: ' + myNewTest.testNumber2);
});
module.exports = router;
When I try to execute curl -X POST http://localhost:3000/tests/1 i get error TypeError: myNewTest.reset is not a function. I am having trouble understanding how to export functions correctly. If I understand this api reference correctly, to expose constructor of module, i have to use module.exports = Test;, but that doesn't expose reset function. So, to expose it I have declared it like exports.reset = function() {...}, but obviously, that doesn't work, at least not in my case.
Through some other answers I have also seen function being declared normally function reset() {...}, and exposed like exports.reset = reset;, which gives me the same error.
How do I expose reset function properly?
You should add it to the prototype, at the moment it's just a static method in your module, not attached to the Test constructor.
function Test(id, testNumber1, testNumber2) {
this.id = id;
this.testNumber1 = testNumber1;
this.testNumber2 = testNumber2;
};
Test.prototype.reset = function() {
this.testNumber1 = 0;
this.testNumber2 = 0;
};
module.exports = Test;
Related
Let's say I have a normal mjs file and an API such as this:
// Storage.mjs
class Storage {
constructor(name, age) {
this.name = name;
this.age = age;
this.json = JSON.stringify(this);
}
}
var store = new Storage('eMart', 2);
// server.js
var express = require('express'),
fs = require('fs'),
data = fs.readFileSync('website/js/storage.mjs'),
convert = JSON.parse(data);
var app = express(),
server = app.listen(3000, initialize);
console.log(convert);
function initialize() {
console.log("Local Host Initialized.");
}
app.use(express.static('website'));
My goal is to send the JSON data to API which is inside of class syntax, but every time Node keeps throwing undefined and an error like this picture;
Most of people's question was sending data from API to specific js file which was totally opposite of my case. It was hard to find solution from there.
Are there any proper ways to pass JSON data to API?
I suppose this is what you want?
// assume this is loaded with fs.readFileSync
const mjs = `
class Storage {
constructor(name, age) {
this.name = name;
this.age = age;
this.json = JSON.stringify(this);
}
}
var store = new Storage('eMart', 2); // I assume you missed the quote here
`;
eval(mjs); // You can't just convert an js file into a JSON, you have to eval it first(not safe, use it with caution)
let result = JSON.parse(store.json); // Since the file outputs a variable called "store" and it has a "json" property
console.log(result);
The server.js snippet
// server.js
var express = require('express'),
fs = require('fs'),
data = fs.readFileSync('website/js/storage.mjs');
(0, eval)(data); // indirect eval
var convert = JSON.parse(store.json);
var app = express(),
server = app.listen(3000, initialize);
console.log(convert);
function initialize() {
console.log("Local Host Initialized.");
}
app.use(express.static('website'));
I want to pass my logServiceClient object to all other modules included in server.js file. When I run below code it prints empty object;
logServiceClient{}
Is there any way to pass logServiceClient to all other included modules?
server.js file;
....
const logger = new Logger({
level: new CLevel('warn'),
ordered
})
var logServiceClient = require('./app/logServiceClient')(logger)
var userHandler = require('./app/userHandler')(logServiceClient)
userHandler file;
module.exports = function(logServiceClient){
console.log('logServiceClient' + JSON.stringify(logServiceClient))
}
There a many ways to inject without pulling in the logger from your other modules.
Use a factory to indirectly create and initialize your objects/modules
function factoryCreateModule() {
var client = require('client')
client.$logger = require('logger')
}
function factoryRequireModule(module) {
var client = require(module)
client.$logger = require('logger')
}
var client = factoryCreateModule()
client.logger.log('hello')
var client2 = factoryRequireModule('client')
client2.logger.log('hello')
Add your logger to all objects using prototype
Of course you can narrow down the target object...
var logger = {
log(message) {
console.log(message)
},
warn(message) {
console.log('!!! ' + message)
}
}
Object.prototype.$logger = logger
var x = 12;
x.$logger.log('I am a number')
var str = "Hello"
str.$logger.warn('WARNING FROM STRING')
Make your logger global
global is the 'window' in the module system.
// just for snippit to run
window.global = {}
var logger = {
log(message) {
console.log(message)
}
}
// main module
global.$logger = logger
// client module
global.$logger.log('hello world')
Pass the logger into the constructor or init method
var logger = require('logger')
var client = require('client')(logger)
var client2 = require('client2')({logger})
var client3 = require('client3')
client3.init(logger)
// file1.js
var foo = "bar";
exports.foo = foo;
//file2.js
var myModule = require('./file1');
var foo = myModule.foo;
Does require and module.exports in NodeJS could be used to obtain all functions in all JavaScript files residing in a directory rather than in a single JavaScript file? If so HOW? Could anyone please explain it with an example ?
If require is given the directory path, it'll look for an index.js file in that directory. So putting your module specific js files in a directory, creating an index.js file & finally require that directory in your working js file should do. Hope example below helps....
Example:
file: modules/moduleA.js
function A (msg) {
this.message = msg;
}
module.exports = A;
file: modules/moduleB.js
function B (num) {
this.number = num;
}
module.exports = B;
file: modules/index.js
module.exports.A = require("./moduleA.js");
module.exports.B = require("./moduleB.js");
file: test.js
var modules = require("./modules");
var myMsg = new modules.A("hello");
var myNum = new modules.B("000");
console.log(myMsg.message);
console.log(myNum.number);
By using require
you required the module in that file and you can use the all function of that prototype (single file ) not a complete directory.
e.g
function admin(admin_id)
{
//console.log(parent_id);
this.admin_id = admin_id;
}
//default constructor
function admin()
{
admin_id = null;
self =this;
}
//destructor
~function admin(){
this.admin_id = null;
console.log('admin obj destroyed!');
}
//exporting this class to access anywhere through data encapstulation
module.exports = admin;
//class methods
admin.prototype = {
help:function(params){
console.log('hi');
}
},
you can require this module and can use the function help
and by this method u can require all file (modules) in single file
Wiki: "Node.js is an open-source, cross-platform runtime environment for developing server-side Web applications.
Although Node.js is not a JavaScript framework, many of its basic modules are written in JavaScript, and developers can write new modules in JavaScript.
The runtime environment interprets JavaScript using Google's V8 JavaScript engine."
Nodejs example:
You have Afile.js
var Afile = function()
{
};
Afile.prototype.functionA = function()
{
return 'this is Afile';
}
module.exports = Afile;
And Bfile.js
var Bfile = function()
{
};
Bfile.prototype.functionB = function()
{
return 'this is Bfile';
}
module.exports = Bfile;
The Test.js file require Afile.js and Bfile.js
var Afile = require(__dirname + '/Afile.js');
var Bfile = require(__dirname + '/Bfile.js');
var Test = function()
{
};
Test.prototype.start = function()
{
var Afile = new Afile();
var Bfile = new Bfile();
Afile.functionA();
Bfile.functionB();
}
var test = Test;
test.start();
Im using node JS aplication and I've created new js file with module and In this module I export just one function,in this module lets say I've additional two functions for internal use only and should not be exposed outside, each function use different require modules like following:
module.exports = function (app, express) {
var bodyParser = require('body-parser'),
url = require('url'),
http = require('http');
.....
};
function prRequest(req, res) {
httpProxy = require('http-proxy');
....
}
function postRequest(req, res) {
url = require('url');
....
}
My question is from best practice where should I put the require (for url http etc)
1.inside every function that need it?in my case internal and external
2.globally in the file that every function can use?
3.if two is not OK where should I put the require URL which I should use in two functions?better to put in both function or in global or it doesn't matter
The modules should be exposed outside the functions as calling require each time the function is called adds extra overhead. Compare:
const url = require('url');
const start = Date.now();
for (let i = 0; i < 10000000; i++) {
url.parse('http://stockexchange.com');
}
console.log(Date.now() - start);
to:
const start = Date.now();
for (let i = 0; i < 10000000; i++) {
require('url').parse('http://stackexchange.com');
}
console.log(Date.now() - start);
On my machine, the former takes 95.641 seconds to finish executing, while the latter takes 125.094 seconds. Even if you export the function that uses the required module, it will still have access to other variables within its file when imported. So I would declare the modules locally in each file where they're needed, and not globally.
Edit: this would mean you'd want to do this instead:
var bodyParser = require('body-parser'),
url = require('url'),
http = require('http');
module.exports = function (app, express) {
....
};
var httpProxy = require('http-proxy');
function prRequest(req, res) {
...
}
I'm trying to build my first node app. My app.js file is shown below. I want to access this from aother module by doing 'app = require('app')'. I then want to access app.app, app.dbConn and app.models
The problem is that when I require this module, app.models is not present on the resulting object.
var express = require('express');
var path = require('path');
var orm = require('orm');
var settings = require('./config/settings');
var mainRouter = require('./config/routes');
var environment = require('./config/environment');
var db = require('./config/db');
var auth = require('./modules/auth');
module.exports = new function(){
this.app = express();
// middlewares must be added in order - start with the basics
environment(this.app);
if (process.env.TESTING) { dbSettings = settings.dbTesting; }
else { dbSettings = settings.db; }
// add models to the request early in the middleware chain
this.dbConn = orm.connect(dbSettings, function(err){
if (err) return console.error('DB Connection error: ' + err);
else{
this.models = db.init(this.dbConn);
this.app.use(function(req,res,next){
req.models = this.models;
next();
});
passport = auth.init(this.models);
authRouter = auth.router(passport)
this.app.use('/users', authRouter);
this.app.use(mainRouter);
}
}.bind(this));
this.app.listen(settings.port);
console.log('Server started... listening on port ' + settings.port)
}
The only way to implement what I wanted was with a function that takes a callback, in the end I rewrote my code thus:
var express = require('express');
var path = require('path');
var orm = require('orm');
var settings = require('./config/settings');
var mainRouter = require('./config/routes');
var environment = require('./config/environment');
var db = require('./config/db');
var auth = require('./modules/auth');
var app;
module.exports = function(cb){
app = express();
// middlewares must be added in order - start with the basics
environment(app);
if (process.env.TESTING) { dbSettings = settings.dbTesting; }
else { dbSettings = settings.db; }
// add models to the request early in the middleware chain
dbConn = orm.connect(dbSettings, function(err){
if (err) return console.error('DB Connection error: ' + err);
else{
models = db.init(dbConn);
app.use(function(req,res,next){
req.models = models;
next();
});
passport = auth.init(this.models);
authRouter = auth.router(passport)
app.use('/users', authRouter);
app.use(mainRouter);
cb({
dbConn: dbConn,
app: app,
models: models
});
}
});
}
if (!process.env.TESTING) {
module.exports(function(server){
server.app.listen(settings.port);
console.log('Server started... listening on port ' + settings.port)
});
}
app.models is defined only once database connection is completed: you cannot use it right away after requiring the module. You should provide an entry point that accepts a function to call once the connection is ready and call this function inside the orm.connect callback.
Even the "server started" message is a bit misleading as it's shown before the server can actually do anything because the function passed to orm.connect has not been called yet.
app.models is never defined so it is never available.
Instead, try
app.set('models', db.init(this.dbConn);