I'm using Mongoose with MongoDb and I'm having trouble figuring out the Javascript code to run all my Mongoose models (one model in each file inside a directory) and initialize all of them.
Basically my file structure is like this:
models
-- User.js
-- Discussion.js
-- Node.js
-- etc.js
index.js
I need an initialize function inside index.js that will run each of the functions in the models. Any ideas?
Were you thinking about something like this? This will include all the files inside models and then run the module.exports function for each of them. This will essentially initialize all your models.
(index.js)
exports.initialize = function() {
require("fs").readdirSync(__dirname + "/models").forEach(function(file) {
require('./models/' + file)();
});
};
Related
This is kind of a silly question, but I want to be able to write code in different files, and then import the code and use it all, like have it written in different files and it all work together.
like this:
routes
login.js
register.js
views
index.ejs
login.ejs
register.ejs
app.js
so if I create a function inside register.js, how do I say, hey, call that function in login.js now, and have it work? do I have to import the files all in app.js? I have only done small projects where this hasn't been necessary, but now I need to :)
Thanks for the help
You can use module.exports object to make your function accessible in another file.
let's say you have defined 2 functions in register.js as follows
const registerfunction1=()=>{
console.log("console registerfunction1")
}
const registerfunction2=()=>{
console.log("console registerfunction2")
}
module.exports={
registerfunction1,
registerfunction2
}
Now you can call these functions any file by using the node require as follows.
for example
//importing register module
const register=require('./register');
const loginFunction=()=>{
// calling function defined in register
register.registerfunction1();
console.log("loginFunction");
};
//calling function
loginFunction();
I am working on installing multiple databases in one server. To start this process, I am assigning one database in the index.js export object such that I will be able to add another DB as I build up the system. Below is the description of the issue.
When I run the server.js file, the .sync function for the database db1 syncs Table1 and Table2 and then begins listening on its port. Its clear the server.js file is receiving the module.exports = db through the var db = require('./models'). However in the file models/Table1.js the server throws an error TypeError: Cannot read property 'Table1' of undefined. I did check the console output for db in the models/Table1.js and it's empty, so its clear module.exports = db is not being accessed in this model.
Can someone provide a solution to correct this issue?
The partial code for the Table1.js model and other files listed above is below:
models/Table1.js
var db = require('./.')
[...]
var new_instance = db.db1.Table1.build({...})
server.js
var db = `require('./models')`
[...]
db.db1.sync(function(err) {});
models/index.js
var sq = new Sequelize(dbname, user, password, config);
db['db1'] = {
Sequelize: Sequelize,
sequelize: sq,
Table1: sq.import(__dirname + '/...'),
Table2: sq.import(__dirname + '/...')
}
module.exports = db;
The module.exports = db is being accessed, but you have created a cyclic dependency between models/index.js and models/Table1.js due to the fact that in the Table1.js model you require index.js file and in the index.js file you perform sequelize.import() call which performs require(path) to include the model definition, so in your case it calls require('./Table1.js') - there comes the cyclic dependency.
You should consider putting the var new_instance = db.db1.Table1.build({...}) somewhere else in order to avoid this situation. Files with model definitions should be only used to create the Model definitions, try to avoid performing additional operations.
Take a look at this question - How to deal with cyclic dependencies in Node.js to find out how you can deal with this kind of situations.
EDIT
According to your comment let's consider simple example with below structure
- script.js
- models
- index.js
- Table1.js
In script.js
var db = require('./models');
var new_instance = db.db1.Table1.build({...});
It can be done if you would not require the script.js inside any of the files placed inside models directory.
How do I export a number modules via an index.js file while making sure they don't impact performance? Probably best explained with a source code:
// index.js
module.exports = {
Database : {
db : db,
},
Helpers : {
_ : lodash,
util : util
}
};
I am trying to avoid loading the Database dependency if all I need is Helpers.util.
using the snippet below, which is what I am using is also loading the Database dependency every ime:
const Core = require('#myapp/core');
const util = Core.Helpers.util;
my package.json is setup as:
{
...
"main": "src/index.js",
...
}
I have some ideas of what should be able to happen, but not sure the best way to address this:
package.json - is there a way to specify multiple main locations?
index.js javascript file - can I do anything else in the javascript file, like wrapping it in a function?
write the require in a different way? like const util = require('#app/core/src/Helpers/util');
I'm building my first Express app. It's a bit messy as my controllers and my models are all in the same place: the app.js file.
Is there a way that I can separate those?
Even artificially, by creating different files and then using some third party program to compile them into the app.js file.
First of all, you need to create your controllers and model folders.
You can use a module called express-load which can be used to autoload models, routes, schemas, configs, controllers, object maps... etc...
in your main file, mine is called app.js you load them right before start the server code line.. it should look like
//requires....
var load = require('express-load');
//your code
load('models')
.then('controllers')
.then('routes')
.into(app);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express listening on port "+ app.get('port'));
});
module.exports = app;
Then, your view folder you can create folders to keep your code organized, then subfolders, I created a folder called home, and inside of it my index view.
In my controllers folder I created a js file called home.js, and which will look for my index view:
module.exports = function(app){
var HomeController = {
index: function(req, res){
res.render('home/index');
}
};
return HomeController;
}
At last in your routes folder, you can set your application routes, each view needs to be specified in your controller. My file for routes its called home.js
module.exports = function(app){
var home = app.controllers.home;
app.get('/', home.index);
}
What I generally do it is to write a module which contains all the routes definition and load it in app.js e.g
require('./routes')(app);
My ./routes.js generally looks like this
module.exports = function (app) {
log.info('Loading express routes...');
/* registration */
app.post('/users', require('./routes/register-users')); // register user
app.post('/agents', require('./routes/register-agents')); // register agents
};
and I keep all the routes (.js) files inside a directory call routes
Hope it is what you are looking for.
Is there a way that I can separate those?
Yes, and you should separate them.
What most people do is declare the routes in the main app.js file and include separate files for the controllers (just like Rituparna described).
Those controllers files will in turn very likely include your model files via a require. For example.
In app.js
var blogRoutes = require('./routes/blogRoutes');
app.get('/api/blog/all', blogRoutes.all);
In routes\blogRoutes.js
var model = require('../models/blogModel');
var all = function(req, res) {
// your controller logic
// and very likely calls to your model
var m = model.blog(whatever);
res.send(m.something());
};
module.exports = {
all: all
}
In models\blogModel.js
var something = function() {
return "something";
};
module.exports = {
something: something
}
You can see a working version of this in this repo https://github.com/hectorcorrea/hectorcorrea.com
You should checkout the examples from the Express Github repo, there are multiple ways to do this (based on personal preference):
https://github.com/visionmedia/express/tree/master/examples/mvc
https://github.com/visionmedia/express/blob/master/examples/resource/app.js
https://github.com/visionmedia/express/tree/master/examples/route-separation
There are some examples here that may help you..
Route Separation: https://github.com/visionmedia/express/tree/master/examples/route-separation
MVP: https://github.com/visionmedia/express/tree/master/examples/mvc
Using this link as a reference https://github.com/visionmedia/express/tree/master/examples/route-separation to what "could be done"
I AM NOT USING EXPRESS. I AM USING THEM AS AN EXAMPLE.
I want to do something like this but "simpler" ...
How can I get away from declaring all my routes in one long, complex list all in one file? Can I define them by passing a router into my modules, and then including all the code in one directory ... ok, I'll suffer having one long document that only does "require" includes, like an index.js, for this one ~ at least that one my build scripts can rebuild for me, but preferably not in my primary file for every single route that I may add.
So for instance, they use this code:
// General
app.get('/', site.index);
// User
app.all('/users', user.list);
app.all('/user/:id/:op?', user.load);
app.get('/user/:id', user.view);
app.get('/user/:id/view', user.view);
app.get('/user/:id/edit', user.edit);
app.put('/user/:id/edit', user.update);
// Posts
app.get('/posts', post.list);
I want to avoid making a list like that in my app.js. I want instead to have each file know what the routes are for that file.
Here's what I'm wanting to do: (please don't critique the code, I'm making it very simple so I make sure that I am illustrating my code the way I want to do it)
//app.js
var router = require('./myRouter.js')
var includes = require('./routes/*.js').register(router)
// do some stuff here with an https server and start the server here
and
//./routes/user.js
var myRouter;
exports.register(router){
myRouter = router;
}
router.addRoute(/* here I do the magic associated with this route */)
Can I do it just that simply? What am I missing here?
I haven't written this code because I'm just ever so certain that I'm going about this the wrong way.
And if I am going to have to use something like an index.js in the /routes/ folder, can I use that same concept that I demonstrated I would like to use in my code of .register(router) appended so I can pass that information down recursively? Would that work?
I use an index.js file for this and use require("routes") which is a folder.
// app.js
route = require("./routes"),
...
route(app);
// routes/index.js
var index = require("./index-route"),
about = require("./about-route"),
posts = require("./posts-route");
module.exports = function(app) {
index(app);
about(app);
posts(app);
};
This works because if you require a folder it will load index.js by default.
If you have a lot of routes you might want to load them based on convention
var routes = [];
// read all files
fs.readdir("./", function(files) {
files.forEach(function(val) {
// require all non-index.js files.
if (val !== "index.js") {
routes.push(require(val));
}
});
});
module.exports = function(app) {
// for each route you required call it with app.
routes.forEach(val.bind(null, app));
}
This would load all .js files that are not "index.js", so any file in your /routes/ folder would be loaded and run when you route them.
Your solution looks vaguely like you wish to use the Visitor Patern, in which case I suggest you make ./roots/ require-able (see this question) and in index.js you include all the files you wish (as local's) and export a register module which calls the register module on each of the required files.
Or you could copy the code from the above answer directly into your main file.