I have a problem understanding NodeJS require().
Basically I have this 3 files:
moongooseconfig.js
var config = require('./config');
var mongoose = require('mongoose');
module.exports = function() {
var db = mongoose.connect(config.db);
require('../app/models/user.server.model');
return db;
}
usercontroller.js
var User = require('mongoose').model('User');
exports.create = function(req, res, next) {
var user = new User(req.body);
user.save(function(err) {
if(err) {
return next(err);
} else {
res.json(user);
}
});
};
And the server.js
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var mongoose = require('./config/mongooseconfig');
var express = require('./config/express');
var db = mongoose();
var app = express();
app.listen(3000);
My understanding of require was that the required module is only visible in the JS file which required the module.
I do not get why the user controller can use the mongoose Model 'User' without requiring the model file.
Yet the mongooseconfig requires the model file inside a function without saving it to a variable.
Can somebody tell me what happens there? Can every file access modules once they where required anywhere?
(Maybe I 'm just to blind, but I can not find the answer in the Node docs and googling "nodejs require scope" does not gave me any good results)
Comments to answer:
mongoose keeps a reference to each of its models. require is just regular JavaScript; it returns an object, and that object has no unusual restrictions on it. The require in mongooseconfig.js is still necessary, though; without it, app/models/user.server.model[.js] will never run and register a model with mongoose.
Related
I have a question about the require function of Node.js, imagine we have a module that manages the connection, and many small modules that contain the routes.
An example of connection file: db.js
const mysql = require('mysql');
const connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'chat'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
and one of the various files to manage the routes:
const app = express();
const router = express.Router();
const db = require('./db');
router.get('/save',function(req,res){
// some code for db
});
module.exports = router;
Imagine now to have 20 routes with the same require. How will node.js behave? How many times will my connection be created?
How many times will my connection be created?
There will be one connection, because "db.js" runs only once. The things you export get stored (module.exports) and that gets returned by every require("./db"). To verify:
require("./db") === require("./db") // true
I'm creating a programmer job board app and I'm trying to display json data on my main page. At some point I'll render it, but for now I'm just trying to get it to show up in json form so that I know it works.
I'm able to connect to the server, but when I load the page I get a TypeError (Job.showAllJobs is not a function).
I'm using a crud app I made the other week as a reference, but there are a few differences between it and this project that are throwing me off.
Here's my project's file structure:
job-board
database
connection.js
schema.sql
models
Job.js
User.js
views
index.ejs
login.ejs
server.js
Unlike my previous crud app, this project is using a connection.js file that gave some trouble earlier. At first I thought I was out of the woods, but I think it might be responsible for my current problem.
Not getting GET to work might seem like a minor error, but it's really bugging me and I haven't been able to keep working because of it.
I populated my table (jobs) with a sample listing as a test, but in the very near future I plan on connecting the app to the GitHub jobs api.
server.js:
const express = require('express');
const app = express();
const PORT = 3000;
const bodyParser = require('body-parser');
const methodOverride = require('method-override');
const Job = require('./models/Job');
const User = require('./models/User');
const connection = require('./database/connection')
app.use(bodyParser.json())
app.use(methodOverride('_method'));
const urlencodedParser = bodyParser.urlencoded({ extended: false })
app.set("view engine", "ejs");
///// GET /////
// GET INDEX
app.get('/', (request, response) => {
Job.showAllJobs().then(everyJob => {
response.json('index');
// response.render('index', { jobs: everyJob });
});
});
Job.js
const Job = {};
const db = require('../database/connection');
///// JOBS /////
/// INDEX ///
Job.showAllJobs = () => {
return db.any('SELECT * FROM jobs');
};
module.exports = Job;
module.exports = db;
connection.js
// require database setup to use pg-Promise
const pgp = require('pg-promise')({});
// connection url
const connectionURL = "postgres://localhost:5432/job_board";
// new database connection
const db = pgp(connectionURL);
// module.exports = db;
You have a couple of problems here.
Make sure you're passing the jobs into res.json instead of the string 'index'
Make sure you're exporting db from connection.js
You're exporting both Job and db from Job.js. Since you're exporting db second, it's overriding the export of Job.
I am trying to take a user input and save it to a collection in my database. I am using Node.js, mongodb, mongoose, express.js and ajax.
I am currently trying to take the post when the user submits the form and take the input and save it to my data base from inside of my module.exports in my controller file.
I was able to make this work when all of the code was in one place inside the server.js but in an attempt to break my code apart appropriately I am trying to separate into a MVC system.
My addProductGroup controller looks like this:
//bring in models of data
var groups = require('../models').Groups;
var express = require('express');
var app = express();
//page functions go inside of module.exports
module.exports = {
index: function(req, res){
groups.find({}, function(err, groups){
if(err){
console.log(err);
}else{
res.render('addProductGroup',{title: 'Admin Add Group', adminloggedin: true, subtitle: 'Add a Group', underheaderp: ''});
app.post('/admin/addProductGroup', function(req,res){
var newGroupName = req.body.groupname;
new groupName({
groupName: req.body.groupname,
}).save(function(err, doc){
if(err){
res.json(err)
}
else {
res.render('addProductGroup',{title: 'Admin ASS Group', adminloggedin: true, subtitle: 'Add a Group', underheaderp: ''});
}
});
});
}
});
}
}
My controller is getting my data from my groups collection and then rendering my page. Then when the user posts the data I am trying to make it take the post data, save it to my database and then render the same exact page. I have played a lot with the nesting of my functions and order of operations.
My groups.js Model :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var GroupsSchema = new Schema ({
groupName: String
});
module.exports = mongoose.model('groups', GroupsSchema);
var groupName = module.exports;
I am using a handlebars template for my views.
So is having all of this in my module.exports a possible thing to accomplish?
Do i need to try and write a function outside of my module.exports to make this work?
If you need to see any of my other files just let me know.
Any help is greatly appreciated.
You do not clarify the issue you have, so I will try to provide you some general help:
Concerning organizing your express application you definitly should take a look at the Version 4 introduced Routers.
You can bind your routes directly on the router object and so seperate your logic into different files (modules).
Your party.js router could look like:
var express = require('express').Router()
router.get('/paricipants', function(req, res) {
res.send('dave','mike')
})
module.exports = router
You can have several such routers (controllers) in your controllers directory (i.e. /controllers). Taking full advantage of the module.exports functionality, you may now put an index.js file in this directory, which then will be loaded by default, as you require the directory.
Your index.js file in your controllers directory could look like:
var router = require('express').Router()
router.use('/party', require('./party'))
// Your other routes to controllers and eventually global routes here.
module.exports = router
You can then simply require this one module in your app.js:
var app = express()
app.use(require('./controllers'))
...
Now just require your mongoose models inside your controllers as you need them.
This will give you a more modular and structured application design.
Hope it helps.
I use nodejs express and mongoose to connect mongodb,I've created a config.js in root folder.I am trying to exports db connect in db.js and trying to import in adminController.js
But when I run the server and refresh the browser ,it log me some errors and not log my log in terminal.
config.js
module.exports = {
cookieScret:'ThreeKingdoms',
db:'threekingdoms',
host:'localhost',
port:27017
}
db.js
var mongoose = require('mongoose'),
config = require('../config'),
connection = mongoose.connection;
module.exports = function(mongoose){
return mongoose.connect('mongodb://'+config.host+'/'+config.db);
}
adminController.js
var express = require('express'),
router = express.Router(),
mongoose = require('mongoose'),
mainInfo = require('../models/admin'),
db = require('../models/db');
router.get('/', function(req, res) {
res.render('admin', { title: 'hey im here!how are you' });
db.on('error',console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log(db)
});
console.log(db)
});
router.post('/',function(req,res,next){
//console.log(req.body)
var mainInfo = mongoose.model('mainInfo');
})
module.exports = router;
question files is in red box
terminal error
I am new to nodejs,so please help me,Thanks
First, it seems that you don't have kerberos installed. Please run npm install kerberos.
Also, the line
Can't set headers after they're sent
Suggests you're trying to modify/send the response after it was already sent back to the client, and that's the error you're getting.
finally it is work now,but it doesn't matter with 'kerberos' ,it is i use wrong way to export my module.terminal still log me 'kerberos undefined' but web can work,i think maybe some time i will try to figure this question out.thanks for your attention
Say i have this code to separate routes in expressjs:
module.exports = function(express,app,client) {
app.get('/', function(req,res,next) {
var query = 'SELECT * FROM users LIMIT 10';
var user = client.query(query, function (err, results, fields) {
res.render('index', {
title: 'test',
users: results
});
client.end();
});
});
}
And require it in app.js:
require('./controllers/routes.js')(express,app,client);
1) How do i separate db queries into new files in the best way?
This file would get pretty big even if i separate db logic.
2) What is a good way to separate routes? Maybe separate modules? and then require them all in app.js?
There is a similar question here which you should read: How to structure a express.js application?
1) All your query logic should be put in models (modules that reside in /models for example)
2) Separate all your routes (controllers) into modules (and put them in /routes for ex)
By routes I mean for example:
- all the logic for "Users" routes go into /routes/users.js
Try to keep you app as MVC-ish as possible.
Small example for your app above:
app.js
// configuration for express etc
require('./routes/index')(app)
routes/index.js
var model = require("../models/users.js");
module.exports = function (app) {
app.get('/', function (req, res, next) {
model.get_recent(function (err, results) {
// do stuff with your results
res.render('index');
});
});
}
models/users.js
module.exports = {
get_recent: function(callback) {
var query = "SELECT * FROM users LIMIT 10";
database.query(query, callback);
}
}
In the expressjs download package, there is a folder called "mvc". The author provides a good example for a tiny&efficient mvc structure. Going through the code, you will get much inspiration.
How about express-train ? i have been using it lately, and it plays well with complex app structures.