Express.js db module after refactoring routes - node.js

I had a simple app in node/express and after watching a course on the net, it helped me refactor the routes in my app but I found a little problem after doing so.
The problem is that my routes are using a variable called "db" that is an instance of a nedb access point.
var db = {
users: new nedb({ filename: "db/users.db", autoload: true })
};
Of course I can copy the 5 lines of code in the top of every route file to declare it but that would not be very DRY.
I tryed to put it in a separate file and export the variable:
...
module.exports = db;
And then import it in every file with:
var db = require("./db");
...
But this didn't worked as expected (The error was : Cannot find module './db')
This is a simplified structure of my files
db/
users.db
routes/
users.js
app.js
db.js
Any ideas or best practice/elegant way for solving this?
Thank you.

you need to require with a relative path. If you require inside /routes folder, you must write
var db = require("../db");

Related

Exported object is empty

I'm struggling since 2 days on something that shouldn't block me.
Basically, I'm building a nodeJS app that uses Express.
In my main file (located in my root folder), i'm exporting some variables/consts, for the purpose of the example I replaced them like this :
// ./index.js
const test = 'test'
module.exports = { test }
... some express initialization/routers
I then have another file that I want to use the "test" variable in, so I require my main file :
// ./aaa/bbb/ccc/test.js
const { test } = require('../../../index);
const myRouter = require('express').Router();
myRouter.get('/', function (req, res){
console.log(test) // undefined
})
I don't really know why it would be undefined as I correctly exported it, and "imported" it through my require statement.
I also tried "consoling" the whole object that I should receive, and it's empty : {}
EDIT : my "main" script that i'm executing is indeed index.js, but I highly doubt it's the reason of the problem
I can't really find out what could be the problem, and I need to export some variable to access them in my project
Thanks!
I think you did it right. The problem may be that es6 features are not acceptable on your node version. Try it like: module.exports = { test:test }.

Cannot find module './models/user' | Node.js

I am making auth in node.js and I have a dir called models, and a file in there to make the user, called user.js.
In the app.js file is the statement var User = require('./models/user');, and yet it can't find that file.
Did you add module.exports = ... // function or object or other variable in the user.js file at the bottom?

Dealing with Relative Paths with node.js

I'm wanting to include a .db database file for use with sqlite3 in my node.js project. My problem arises when the module which opens the database connection is required by files in different directories.
My project structure is like so:
project/
|--lib/
| |--foo.js
| `--bar.js
|--db/
| `--database.db
`--server.js
My foo.js file contains opens the database like so:
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database('db/database.db');
module.exports = {
foo: function() {
db.serialize(function() { /* Do database things */ });
}
};
This all works fine when foo.js is required from the server.js file like so:
var foo = require('./lib/foo');
But it doesn't work when required from the file inside the lib directory, bar.js.
var foo = require('./foo');
I assume this is because when this file is initiated from the lib directory then the .db file should actually be ../db/database.db.
How can I get around this, what should I do?
the concept current directory differs when using sqlite3.Database function in different scripts. it works as designed in this line of sqlite3 source code.
So you should explicitly specify the current directory every time you use it. According to your project layout, the correct path to database file in lib/foo.js is
var path = require('path')
// specify current directory explicitly
var db = new sqlite3.Database(path.join(__dirname, '..', 'db', 'database.db'));
Then it works no matter where it requires foo.js.

grunt + mochaTest: Change working directory?

I`m trying to implement testing for my nodejs-project with grunt-mocha-test and have issues with different/incorrect paths.
Like I saw it elsewhere, I want to get all dependecies by just requiring my server.js.
gruntfile.js
mochaTest: {
test: {
options: {
reporter: 'spec',
require: 'app/server.js'
},
src: ['app/test/**/*.js']
}
}
My current project structure looks like this
gruntfile.js
app/server.js
app/models/..
app/controllers/..
app/tests/..
users.controller.test.js
var userCtl = require('../controllers/users.controller');
describe("return5", function () {
it("should return 5", function () {
var result = userCtl.return5(null, null);
expect(result).toBe(5);
});
});
users.controller.js
var mongoose = require('mongoose');
var User = mongoose.model('User'); // <- Mocha crash: Schema hasn't been registered for model "User".
..
In my server.js I use:
..
// config.js: https://github.com/meanjs/mean/blob/master/config/config.js
config.getGlobbedFiles('./models/**/*.js').forEach(function (path) {
require(path); // never called with mochaTest
});
..
console.log(process.cwd()); // "C:\path\project" (missing /app)
..
So the cwd is different to what it should be.
Can someone please help me getting around this issue?
I will clarify the title as soon as I know what I`m doing wrong.
Thank you.
The confusion is due to the difference between module paths and filesystem paths.
When you do require("./blah"), the . is interpreted to mean "start with the path of the current module". Since this is relative to the module you are currently in, it will resolve to different values depending on where the module is located.
When you run process.cwd() this is returning the current working directory of the process. This does not change from module to module. It changes when your code calls process.chdir(). Also, when you perform filesystem operations that use ., this is interpreted relative to process.cwd().
So that you get C:\path\project from process.cwd() is not surprising since this is where you'd typically run Grunt (i.e. at the top level of your project). What you can do if you want paths relative to a module is use __dirname. For instance, this code reads files from a foo subdirectory in the same location where the module that contains this code is located:
var path = require("path");
var fs = require("fs");
var subdir = path.join(__dirname, "foo");
var foofiles = fs.readdirSync(subdir);

Why doesn't my Mongoose schema method "see" my required object?

I'm really confused about a variable scope issue with a file required via a path in a config file. Why does my Mongoose schema method "see" the required objects when called from within the model file but not when called from my app.js file? I'm convinced that I must be doing something obviously wrong but I can't see it.
The Node project has the following (simplified) structure:
|models
-index.js
-story.js
-post.js
-app.js
-config.js
This is config.js:
config = {};
config.test = 'test';
config.models = __dirname + '/models';
module.exports = config;
This is story.js:
var config = require('../config.js');
var models = require(config.models);
var foo = {};
foo.bar = 'baz';
var storySchema = mongoose.Schema
({
author: {type: mongoose.Schema.Types.ObjectId},
root: {type: mongoose.Schema.Types.ObjectId, default: null}
});
storySchema.methods.test = function()
{
console.log(foo.bar);
console.log(config.test);
console.log(models);
}
var Story = exports.model = mongoose.model('story', storySchema);
When I create a new Story in app.js and call its test() method, I get this output:
baz (so I know it's seeing objects in the same file)
test (so I know it's seeing variables in the config file)
{} (this "should" log my models object but it logs an empty object, why?)
When I create a new Story object within the story.js file, and run it (node ./models.story.js) the values returned are as expected (the models object is logged rather than an empty object).
Update, here are the index.js and app.js files:
index.js:
module.exports = {
post: require('./post'),
story: require('./story')
};
app.js:
var config = require('./config');
var models = require(config.models);
var story = new models.story.model();
story.test();
I believe the issue is that you've created a circular dependency. Story executes require(config.models) which requires Story again inside index.js.
Rather than storing a string and requireing it everywhere, try storing the models directly in config.models:
config.js
module.exports = {
test: 'test',
models: require(__dirname + '/models')
};
In case anyone runs into this same issue, I wanted to point to a couple resources I came across that helped me resolve the issue. As ssafejava pointed out, the problem does have to do with circular dependency (although ssafejava's solution did not entirely resolve the issue) . What worked for me was designing this dependency out of my application but there are other options if doing so is not possible. See the following issues' comments for a better explanation (in particular, see 'isaacs' comments):
https://github.com/joyent/node/issues/1490
https://github.com/joyent/node/issues/1418

Resources