export mongo database connection to models.js file - javascript

app.js file:
var express = require('express');
var path = require('path');
var mongoose = require('mongoose');
var bodyparser = require('body-parser');
var conn = mongoose.createConnection('mongodb://localhost/database_name');
var app = express();
app.set('view engine','ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyparser.urlencoded({extended:true}));
app.use(require('./routes/index'));
app.use(require('./routes/page1'));
app.use(require('./routes/page2'));
app.use(require('./routes/page3'));
app.use(require('./routes/page4'));
exports.conn = conn;
app.listen(3000,function(request, response){
console.log("Server is running at Port 3000");
});
models.js file:
var mongoose = require('mongoose');
var app = require('./app');
var conn = app.conn
module.exports.User = conn.model('User', new mongoose.Schema({
username: String,
password: String,
}));
On running node app.js, i am getting an error that TypeError: Cannot read property 'model' of undefined.
app.js and models.js are in the same folder.
P.S. i am using createConnection function because i have to make two database connections.

You should not require app.js inside a module. That defeats the purpose. Either use a separate module that handles the connection, or use dependency injection like this:
models.js
var mongoose = require('mongoose');
module.exports = function(conn) { // inject connection
return {
User: conn.model('User', new mongoose.Schema({
username: String,
password: String,
})
};
}
app.js
var conn = mongoose.createConnection('mongodb://localhost/database_name');
var models = require('./models')(conn);
models.User(...) // do stuff with User function
This is better structured, more maintainable and better testable as you can inject a mock for conn.

finally figured it out:
to make it globally available we need to replace following line
var conn = mongoose.createConnection('mongodb://localhost/database_name');
with
module.exports.conn = mongoose.createConnection('mongodb://localhost/database_name');

Related

Waiting for localhost when trying to connect to node js server

when i run this , i should be able to get mysite at localhost:3000 . but when i go to localhost:3000 it is not loading. chrome is still showing waiting for localhost. This is the code . It is a simple node js blog that uses mongo db. I got it from this github https://github.com/pankajwp/node-js-blog
This is the code for server. Please help
i will add my mongodb credentials to mongoose.connect.
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var expressLayouts = require('express-ejs-layouts');
var mongoose = require('mongoose');
mongoose.connect('');
var Schema = mongoose.Schema;
app.use('/assests',express.static(__dirname + '/public'));
app.use(expressLayouts);
app.use((req, res, next) => {
res.locals.baseUrl = req.baseUrl;
next();
});
// by default express will look for static files inside the filder called views
app.set('view engine', 'ejs');
// Controllers
var pageController = require('./controllers/pageController');
var postController = require('./controllers/postController');
var adminController = require('./controllers/adminController');
var randomController = require('./controllers/randomController');
randomController(app);
adminController(app, Schema, mongoose);
postController(app, Schema, mongoose);
pageController(app, Schema, mongoose);
// Listen
app.listen(port);
console.log('Listening on localhost:'+ port);
Following thing is wrong
// Listen
app.listen(port);
console.log('Listening on localhost:'+ port);
Right away after calling listen, app does not listen immediately to the specified port.
The code should be like following
app.listen(port, function() {
console.log(`Listening on localhost: ${port}!`);
})
What is happening here, listening to a port is a asynchronous task. It is accepting some callback to let you know, what is the status of your listening to the port. If successful, then callback is called.
What your code was doing is, whether the listening to port is success of not, it always prints Listening on localhost: xxxx.
Example taken from directly Express Hello world.
Try This:
const express = require('express');
const ejs = require('ejs');
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const app = express();
const port = process.env.PORT || 3000;
//Create Object like this
const Schema = new mongoose.Schema({
//your properties name goes here like:
name: {
type:String
}
});
app.use('/assests',express.static(__dirname + '/public'));
app.use(expressLayouts);
app.use((req, res, next) => {
res.locals.baseUrl = req.baseUrl;
next();
});
// by default express will look for static files inside the filder called views
app.set('view engine', 'ejs');
// Controllers
var pageController = require('./controllers/pageController');
var postController = require('./controllers/postController');
var adminController = require('./controllers/adminController');
var randomController = require('./controllers/randomController');
randomController(app);
adminController(app, Schema, mongoose);
postController(app, Schema, mongoose);
pageController(app, Schema, mongoose);
//db connection
mongoose
.connect('url goes here, ({useUnifiedTopology: true, useNewUrlParser:true}))
.then(() => console.log('MongoDB connected!!!'))
.catch(err => console.log(err));
app.listen(port, (req, res) => console.log(`Server is running at ${port}`));
you can try with adding this code jsut after declaring your port number.
app.use(bodyParser.json());
your updated code should looks like below and it should work on http://localhost:3000
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
app.use(bodyParser.json());
var expressLayouts = require('express-ejs-layouts');
var mongoose = require('mongoose');
mongoose.connect('');
var Schema = mongoose.Schema;
app.use('/assests',express.static(__dirname + '/public'));
app.use(expressLayouts);
app.use((req, res, next) => {
res.locals.baseUrl = req.baseUrl;
next();
});
// by default express will look for static files inside the filder called views
app.set('view engine', 'ejs');
// Controllers
var pageController = require('./controllers/pageController');
var postController = require('./controllers/postController');
var adminController = require('./controllers/adminController');
var randomController = require('./controllers/randomController');
randomController(app);
adminController(app, Schema, mongoose);
postController(app, Schema, mongoose);
pageController(app, Schema, mongoose);
// Listen
app.listen(port);
console.log('Listening on localhost:'+ port);

How to use express middleware to handle all routes?

I have issue setting up routes for user in below code, I want to use express middleware and trying routes using app.use.
index.js is invoking user controller method once api's is being called So in below code i am trying to post data api/users from client but it returns 404.
How can i fix this issue using below routes setup ?
server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
console.log(mongoose.connection.readyState);
var db = require('./config/db');
var port = process.env.PORT || 8080;
mongoose.connect(db.url);
app.use(methodOverride('X-HTTP-Method-Override'));
app.use(express.static(__dirname + '/public'));
require('./app/routes')(app); // configure our routes
require('./config/express')(app);
app.listen(port);
console.log('listening on port ' + port);
exports = module.exports = app;
app > routes.js
module.exports = function(app) {
app.use('api/users', require('./api/user'));
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html'); // load our public/index.html file
// res.sendFile(path.join(__dirname, ''../public/views/index.html''));
});
};
config > express.js
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
// import cookieParser from 'cookie-parser';
// import errorHandler from 'errorhandler';
var path = require('path');
// import lusca from 'lusca';
var config = require('./db');
var mongoose = require('mongoose');
//var mongoStore = connectMongo(session);
module.exports = function(app) {
// app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
}
User index where i will handle all crud operation for user
app > api > user > index.js
var express = require('express');
var controller = require('./user.controller');
var router = express.Router();
router.get('/', controller.index);
router.post('/',controller.create);
module.exports = router;
1st:
To handle all request
Bind application-level middleware to an instance of the app object by using the app.use() and app.METHOD() functions, where METHOD is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.
This example shows a middleware function with no mount path. The function is executed every time the app receives a request.
app.use(function(req,res)
{
res.sendfile('./public/views/index.html');
console.log("Not found....I will handle *unhandle* rout here for you");
})
// app.get('*', function(req, res) use the above function instead of this
But this function at the end so it will only excute when no route path found to the app object.
Express documentation
2nd:
To handle createuser
var express = require('express');
var controller = require('./user.controller');
var router = express.Router();
// you must define route which you want to handle in user file
router.get('/api/user', controller.index);
router.post('/',controller.create);
module.exports = router;
Update working example with some explanation
Your app.js file
var express=require('express')
var app=express()
app.use('api/user',require('./user'))
app.use('/',require('./user'))
app.use(function(req,res)
{
res.sendfile('stack10.html')
console.log("Not found....I will handle *unhandle* rout here for you");
})
app.listen(8080,function()
{
console.log("server listening on port 8080")
})
user.js
var express = require('express')
var router = express.Router()
var app=express()
router.get('/api/user', function(req, res) {
res.send('respond for ..../api/user')
});
router.get('/',function (req,res) {
res.send('respose for ..../')
})
module.exports = router;
Your app.use will be app.use(api/user) while in user will be router.get(/api/user) so when u try http://127.0.0.1:8080/api/user
your response will be respond for ..../api/user

nodejs module - express module.export - how to pass variable to other file?

Question is how to pass variable to other js file in the simplest way (without any routes just with module.exports).
My file structure looks like this (very simple popular structure):
ROUTES (folder)
--form.js
--test.js
VIEWS (folder)
--form.ejs
--test.ejs
index.js
package.json
index.js file (standard express app file):
var express = require('express');
var body_parser = require('body-parser');
var form = require('./routes/form.js');
var test = require('./routes/test.js');
var app = express();
app.set('view engine', 'ejs');
app.use(body_parser.urlencoded({extended:true}));
app.use('/', form);
app.use('/test', test);
var port = 3700;
var server_listen_on = app.listen(port, function()
{
console.log('Server is listening on port: ' + port);
});
form.js file:
var express = require('express');
var body_parser = require('body-parser');
var router = express.Router();
var preciousData = 'var precious_data - from form.js file';
module.exports =
{
exportsPreciousData : preciousData,
router : router
};
test.js file:
var express = require('express');
var request = require('request');
var router = express.Router();
var requireFormjs = require('./form.js');//({exportsPreciousData : exportsPreciousData});
//console.log(requireFormjs.exportsPreciousData); // I guess console.log is faster then module.exports... but
router.get('/', function(req, res, next)
{
res.render('welcome', {test : requireFormjs.exportsPreciousData});
});
// why this doesn't work - I need to use middleware function - could you provide simple working example?
//(I guessing that even if console.log print data after module.exports machinery I would still need middleware, right?)
module.exports = router;
welcome.ejs file:
<!DOCTYPE html>
<html>
<head>
<title>welcome</title>
</head>
<body>
<%= test %>
</body>
</html>
... why it's not working (without express everything runs fine)?
Simple make those other files return a function:
Test.js:
module.exports = function(preciousData) {
// do everything here
return router;
}
index.js:
var test = require('test.js')(preciousData);
Data is passed by calling the function that test.js returns and router is returned from that function

Mongoose does not save anything to db with NodeJs

I have this very simple code that stores superhero name and power to database.
All connections work normally. When i ran mongod i used --dbpath C:/nodeprojects/sankarit/data. I have tried change the path like 50 times with different paths.
So my code sends nimi and supervoima (name, superpower) from client side and it tries to add them to database but literally nothing happens in db. When i write console.log("yay it works") on save function, it says that its working. And if i console log superhero it seems to work normally.
Here is client side:
$http.post("api/juttu", {nimi: "besthero", supervoima: "whiskey"}).success(function(response){
console.log(response.data);
}).error(function(){
console.log("Error")
})
Here is my server.js:
var express = require('express');
var path = require('path');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.set('debug', true);
// SANKARI SCHEMA
var Sankari = require('./app/models/sankarit');
// CONTROLLERIT
var testCtrl = require('./server/testCtrl');
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.use('/public', express.static(__dirname + '/public'));
// DB conn
// I have tried with /test, /heros, /sankariKanta, /sankarit
mongoose.connect('mongodb://127.0.0.1:27017/test');
mongoose.connection.once('connected', function() {
console.log("Connected to database")
});
//PORTTI
var port = process.env.PORT || 8080;
// ROUTER
var router = express.Router();
app.get('/', function(req, res) {
res.sendFile('index.html', {root: __dirname});
});
app.post("/api/juttu", testCtrl.juttu);
app.listen(port);
Here is the testCtrl:
var Sankari = require("../app/models/sankarit");
module.exports.juttu = function (req, res){
// Tried also var uusiSankari = new Sankari(req.body);
var uusiSankari = new Sankari();
uusiSankari.nimi = req.body.nimi;
uusiSankari.supervoima = req.body.supervoima;
uusiSankari.save(function(err){
if(err){
console.log(err);
} else{
// This is always showing up
console.log("This is working!");
}
});
};
Also when i try console.log(req.body); It is working correctly.
Here is schema(sankarit.js):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SankariSchema = ({
nimi: String,
supervoima: String
});
module.exports = mongoose.model('Sankari', SankariSchema);
When i run the program, the mongoose debug thing says:
Mongoose: sankaris.insert({ __v: 0, _id: ObjectId("57ff0a649dbf169c15000001"), nimi: 'besthero', s
upervoima: 'whiskey' }) {}
So when i debug and console log everything the program does it seems to work like dream. I have made these MEAN stack tutorials like 5-10 and everytime database worked normally. This is first time i'm trying to make whole code by myself. I tried solve this whole night but i didn't get absolutely anywhere.
You forgot to use the Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SankariSchema = Schema({
nimi: String,
supervoima: String
});
module.exports = mongoose.model('Sankari', SankariSchema);

Why is my node express app not fetching data from mongoose?

I have a background in PHP MVC and just started learning Nodejs.
This is my app directory structure:
root
- controllers
-user.js
- model
-user.js
- public
-stylesheet
-style.css
- views
-index.jade
- app.js
- package.json
- gulpfile.js
This is my controller file: user.js
var User = require('../models/user.js');
exports.list = function(req, res){
User.find(function(err, users) {
res.send(users);
});
};
This is my model file: user.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.createConnection('mongodb://localhost/mydb');
var userSchema = new Schema({
name: String,
country: String,
email: String,
password: String,
});
module.exports = mongoose.model('user', userSchema);
Below is my app.js file:
/**
* Module dependencies.
*/
var express = require('express')
, controllers = require('./controllers')
, employee = require('./controllers/employee')
, user = require('./controllers/user')
, http = require('http')
, path = require('path');
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', controllers.index);
app.get('/employees', employee.list);
app.get('/user',user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
I have created a database in mongo using the command line and below is my collections list:
I may still be thinking it the php way and missing some point here. Could someone point out what I am doing wrong here ?
Mongoose automatically looks for the plural version of your model name, more details about this rule please refer to the source code, Mongoose.model definition is
Mongoose#model(name, [schema], [collection], [skipInit])
To solve your issue, you could define your model
mongoose.model('user', userSchema, { collection: 'user' });

Categories