I'm using making error messages available on res.locals and displaying them as needed with a redirect. I am not completely sure how this works, but it does. At least when I'm running the server locally.
Deployed to Heroku on the other hand, it doesn't. There's nothing. I make mistakes on the page and my sexy flash messages are glimmering with their absence.
I'm using sqlite3 locally and storing sessions with connect-session-sequelize.
I'm using postgres on Heroku.
server.js
/* jshint node: true */
'use strict';
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var _ = require('underscore');
var db = require('./db.js');
var SequelizeStore = require('connect-session-sequelize')(session.Store);
var flash = require('express-flash');
var app = express();
var PORT = process.env.PORT || 3000;
app.use(cookieParser());
// Track logins with express session
app.use(session({
secret: 'Magic mike',
resave: true,
saveUninitialized: false,
store: new SequelizeStore({
db: db.sequelize
})
}));
app.use(flash());
// Make userId available in templates
app.use(function(req, res, next){
res.locals.currentUser = req.session.userId;
res.locals.sessionFlash = req.session.sessionFlash;
delete req.session.sessionFlash;
next();
});
// To parse incoming req
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
// Serve static files
app.use(express.static(__dirname + '/public'));
// View engine setup
app.set('view_engine', 'pug');
app.set('views', __dirname + '/views');
var routes = require('./routes/index.js');
app.use('/', routes);
....
db.js
var Sequelize = require('sequelize');
var env = process.env.NODE_ENV || 'development';
var sequelize;
if (env === 'production') {
sequelize = new Sequelize(process.env.DATABASE_URL, {
dialect: 'postgres'
});
} else {
sequelize = new Sequelize(undefined, undefined, undefined, {
'dialect': 'sqlite',
'storage': __dirname + '/data/shoplist.sqlite'
});
}
var db = {};
db.item = sequelize.import(__dirname + '/models/item.js');
db.user = sequelize.import(__dirname + '/models/user.js');
// db.shoplist = sequelize.import(__dirname + '/models/shoplist.js');
db.sequelize = sequelize;
db.Sequelize = Sequelize;
// db.item.belongsTo(db.shoplist);
// db.shoplist.hasMany(db.item);
db.item.belongsTo(db.user);
db.user.hasMany(db.item);
// db.user.belongsTo(db.shoplist);
// db.shoplist.hasMany(db.user);
module.exports = db;
....
routes/index.js
var express = require('express');
var router = express.Router();
var _ = require('underscore');
var mid = require('../middleware/');
var db = require('../db.js');
var flash = require('express-flash');
router.all('/login-error', function(req, res) {
res.redirect(301, '/login');
});
router.all('/register-error', function(req, res) {
res.redirect(301, '/register');
});
// GET /homepage
router.get('/', function(req, res, next) {
req.flash('info', 'Velkommen!');
return res.render('index.pug', {
title: 'Welcome!',
url: req.originalUrl
});
});
....
// POST /login
router.post('/login', function(req, res, next) {
var body = _.pick(req.body, 'name', 'password');
if (req.body.name && req.body.password) {
db.user.authenticate(body).then(function(user) {
req.session.userId = user.id;
// To make sure the session is stored in db befor redirect
req.session.save(function() {
return res.redirect('makeitem');
});
}).catch(function(e) {
var err = new Error("Wrong username or password.");
err.status = 400;
err.message = "Wrong username or password.";
req.session.sessionFlash = {
type: 'error',
message: err.message
};
res.redirect('/login-error');
});
} else {
var err = new Error('All fields required.');
err.status = 400;
err.message = 'All fields required.';
req.session.sessionFlash = {
type: 'error',
message: err.message
};
res.redirect('/login-error');
}
});
...
// POST /register
router.post('/register', function(req, res, next) {
var body = _.pick(req.body, 'name', 'email', 'password');
// Check if all fields are filled out
if (req.body.name &&
req.body.email &&
req.body.password) {
// // Check that passwords are the same
if (req.body.password !== req.body.comf_password) {
var err = new Error('Passwords do not match.');
err.status = 400;
err.message = 'Passwords do not match.';
req.session.sessionFlash = {
type: 'error',
message: err.message
};
res.redirect('/register-error');
} else {
db.user.create(body).then(function(user) {
//res.json(user.toPublicJSON());
res.redirect('/login');
}, function(e) {
var err = new Error('Email or Shopping List Name in use.');
err.status = 400;
err.message = 'There is already a Shopping List with this name or email';
req.session.sessionFlash = {
type: 'error-name',
message: err.message
};
res.redirect('/register-error');
});
}
} else {
var err = new Error('All fields required.');
err.status = 400;
err.message = 'All fields required.';
req.session.sessionFlash = {
type: 'error',
message: err.message
};
res.redirect('/register-error');
}
});
...
I'm using pug, so this is the way I display messages:
if sessionFlash && sessionFlash.message
.sessionflash
p.bg-warning #{ sessionFlash.message }
These are my dependencies:
"dependencies": {
"bcrypt": "^0.8.7",
"body-parser": "^1.15.2",
"connect-session-sequelize": "^3.1.0",
"cookie-parser": "^1.4.3",
"crypto-js": "^3.1.6",
"express": "^4.14.0",
"express-flash": "0.0.2",
"express-session": "^1.14.1",
"jsonwebtoken": "^7.1.9",
"pg": "^4.5.6",
"pg-hstore": "^2.3.2",
"pug": "^2.0.0-beta6",
"sequelize": "^3.5.1",
"sqlite3": "^3.1.4",
"underscore": "^1.8.3"
Why is this happening? And how do I display flash messages on Heroku?
Facing the same issue, I realized that it had to do with Cloudflare settings. Forwarding permissions were causing an issue that erased local variables any time I loaded a page. When I simply used the app deploy link with heroku and I stopped having an issue. If you're reading this in the future, use your command line to test the website in production with "NODE_ENV=production npm start" and web with "heroku local web", if both of those are working fine, the problem may be your dns manager.
Related
I'm trying to create a schema for a user authentication system but keep getting the above error message. I've created two new pages with the following code:
Users.js
var mongoose = require ('mongoose');
var crypto = require ('crypto');
var jwt = require('jsonwebtoken');
var userSchema = new mongoose.Schema({
email:{
type: String,
unique: true,
required: true
},
name: {
type: String,
required: true
},
hash: String,
salt: String
});
userSchema.methods.setPassword = function(password){
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex');
};
//when the setPassword method is called and supplied with a password, the salt and hash will be generated
//for users and added to the model instance - password is never saved anywhere, and not even stored in memory
userSchema.methods.validPassword = function(password){
var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex');
return this.hash === hash;
};
userSchema.methods.generateJwt = function(){
var expiry = new Date();
expiry.setDate(expiry.getDate() + 7);
return jwt.sign({
_id: this._id,
email: this.email,
name: this.name,
exp: parseInt(expiry.getTime() / 1000),
}, process.env.JWT_SECRET);
};
/*var User = mongoose.model('user');
var user = new User();
user.name = "User's name";
user.email = "test#example.com";
user.setPassword("myPassword");
user.save();*/
authentication.js
var passport = require('passport');
var mongoose = require('mongoose');
var User = mongoose.model('User');
var sendJSONreponse = function(res, status, content) {
res.status(status);
res.json(content);
};
//register controller for the API
module.exports.register = function(req, res){
if(!req.body.name || !req.body.email || !req.body.password){
sendJSONreponse(res, 400, {
"message": "All fields required"
});
return;
}
var user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.setPassword(req.body.password);
user.save(function(err) {
var token;
if (err){
sendJSONreponse(res, 404, err);
} else{
token = user.generateJwt();
sendJSONreponse(res, 200, {
"token" : token
});
}
});
};
//Login controller for the API
module.exports.login = function(req, res) {
if(!req.body.email || !req.body.password){
sendJSONreponse (res, 400, {
"message" : "All fields required"
});
return;
}
passport.authenticate('local', function(err, user, info){
var token;
if (err){
sendJSONreponse(res, 404, err);
return;
}
if(user){
token = user.generateJwt();
sendJSONreponse(res, 200, {
"token" : token
});
} else {
sendJSONreponse(res, 401, info);
}
}) (req, res);
};
module.exports = router;
app.js This is some of the code which relates to the above
require('dotenv');
var express = require('express');
var createError = require('http-errors');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var bodyParser = require('body-parser');
var uglifyJS = require("uglify-js");
var fs = require ('fs');
var passport = require('passport');
//require('./app_api/models/blogModel');
require('./app_api/models/db');
require('./app_api/config/passport');
var routesApi = require('./app_api/routes/index');
var mongoose = require("mongoose");
var mongoDB = "mongodb://**********************************;
mongoose.Promise = global.Promise;
mongoose.connect(mongoDB, {useNewUrlParser: true, useUnifiedTopology: true})
.then(() => console.log('connection successful'))
.catch((err) => console.log(err));
/*BRING IN SCHEMAS AND MODELS*/
require('./users');
var app = express();
app.use(bodyParser.json());
app.use(express.static('public'));
app.use(bodyParser.urlencoded({
extended: true
}));
// view engine setup
app.set('views', path.join(__dirname, 'app_server', 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'app_client')));
app.use(passport.initialize());
app.use('/api', routesApi);
//make db accessible to router
// app.use(function(req, res, next){
// req.db=db;
// next();
// });
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
// catch unauthorised errors
app.use(function (err, req, res, next){
if (err.name === 'UnauthorizedError'){
res.status(401);
res.json({"message" : err.name + ": " + err.message});
}
});
module.exports = app;
I've been following a textbook and the formatting etc. is correct; I just don't know where the error is coming from.
Thank you in advance!
At the bottom of Users you need to declare the model, using mongoose.model('Users',userSchema); also export it, you then interact with the model, schema is more of a declaration (details), the model is the implementation providing the functionality you're requiring.
You actually were pretty close, you needed to add the schema argument to the model.
I want to show you my error with NodeJS and MySQL.
Error is at line 45 of app.js
Cannot read property 'end' of undefined
at ServerResponse.<anonymous> (/usr/my_server/app.js:45:24)
It happen when I call a request from 'addReferFriend.js' file.
I link here the two files that I am using.
app.js:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mysql= require('mysql2');
var http = require('http');
var app = express();
var addReferFriend = require('./addReferFriend');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(async function(req, res, next) {
try {
if( req.dbConnection ) {
// ensure that req.dbConnection was not set already by another middleware
throw new Error('req.dbConnection was already set')
}
let connection = mysql.createConnection({
host: 'xx',
user: 'xx',
password: 'xx',
database: 'xx'
});
res.on("finish", function() {
// end the connection after the resonponse was send
req.dbConnection.end()
});
// wait for the connection and assign it to the request
req.dbConnection = await connection.connect();
next();
} catch(err) {
next(err);
}
});
app.use('/api/addReferFriend', addReferFriend);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
module.exports = app;
var server = http.createServer(app);
server.listen(3955);
addReferFriend.js:
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.post('/', function(req, res, next) {
var uid = req.body.uid;
var friendReferCode = req.body.friendReferCode;
var sqlCheckIfExist = "SELECT my_refer FROM hub_user WHERE my_refer = '" + friendReferCode + "'";
var sqlCodeCheckSameAsMine = "SELECT my_refer FROM hub_user WHERE uid = '" + uid + "'";
function checkIfUserCodeExist() {
return req.dbConnection.query(sqlCheckIfExist)
.then(([rows, fields]) => {
if (rows == 0) {
console.log("Non esiste!")
return res.send(JSON.stringify({
"status": 500,
"response": "codeNotExist"
}));
}
console.log("Esiste!")
return checkIfCodeIsSameAsMine(connection)
})
}
function checkIfCodeIsSameAsMine() {
return req.dbConnection.query(sqlCodeCheckSameAsMine)
.then(([rows, fields]) => {
if (rows == friendReferCode) {
console.log("Codice uguale!")
return res.send(JSON.stringify({
"status": 500,
"response": "sameCodeAsMine"
}));
}
console.log("Codice non uguale!")
})
}
checkIfUserCodeExist()
.catch(next)
});
module.exports = router;
I have no idea how fix this type of problem. It happen when I call the checkIfUserCodeExist() and it doesn't join into the function and it gives directly the error. I can't print any of console.log because it break.
Hope that somebody can help me with this issue.
Thanks in advance for the help,
Michele.
it seems to be req.dbConnection.end() the problem... the object dbConnection is undefined.
is it possible that the connection is closed first for some reason? so the point to closing connection is not correct?
When a logged-in user gets to a page through the browser using EJS I'm able to get the function to do what it's supposed to but when I use the API with Ionic using a logged in user with JWT, the async.parallel function doesn't "wait" to do things in order.
Here is my function:
console.log('1');
async.parallel([
function(callback){
buildAlertButtonsArray.getRealTestAlerts(req,function(arrayAlerts) {
console.log('2');
callback(null, arrayAlerts);
});
},
function(callback) {
if(req.decoded) //API
callback('API');
else //EJS
functions.aclSideMenu(req, res, function (acl) {callback(null, acl);}); //aclPermissions sideMenu
}
],function(err, results){
console.log('3');
})
when I login through the browsed on my console.log() is 1, 2, 3 but when I login through the API using JWT I get 1, 3, 2.
Here is my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
var bluebird = require('bluebird');
//me
var mongoose = require('mongoose');
var db = mongoose.connection;
var cors = require('cors');
var session = require('client-sessions');
var flash = require('express-flash');
//.js file
var routesApi = require('./routes/api');
var routesEjs = require('./routes/ejs');
var routes = require('./routes/index');
//var login = require('./routes/authentication/login');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(cookieParser());
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true })); //was FALSE by default. was TRUE for auth Template
// middleware
app.use(session({
cookieName: 'session',
secret: 'mysecret',
duration: 30 * 60 * 1000,
activeDuration: 30 * 60 * 1000,
httpOnly: true, //doesn't let javascript access cookies ever
secure: true, // only use cookies over https
ephemeral: true // delete this cookie when the browser is closed (nice when people use public computers)
}));
app.use(flash());
app.use(function(req, res, next){
res.locals.success_messages = req.flash('success_messages');
res.locals.error_messages = req.flash('error_messages');
next();
});
// use cors
app.use(cors());
app.use('/public', express.static(path.join(__dirname, 'public')));
app.use('/api', routesApi);
app.use('/', routes);
app.use('/', routesEjs);
//bluebird
mongoose.Promise = require('bluebird');
//connecting to database
mongoose.connect('mongodb://myip:2999/SMECS_database', { useMongoClient: true });
//if we connect successfully or if a connection error occurs
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
// yay!
});
// error handlers
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Here is my Login function for both EJS using CSRF and API using JWT:
module.exports.postLogin = function(req, res, next) {
if (req.body.pushToken) { // run SMECS API
models.Users.findOne({
email: req.body.email.toLowerCase()
}, function (err, user) {
if (err) throw err;
if (!user) {
res.json({success: false, message: 'Authentication failed. User not found.'});
} else if (user) {
//check if password matches
if (!bcrypt.compareSync(req.body.pin, user.pin)) {
res.json({success: false, message: 'Authentication failed. Wrong password.'});
} else {
// if user is found and password is right
// create a token
var token = jwt.sign({user: user}, config.secret, {
//expiresIn: 1440 // expires in 24 hours
});
user.save(function (err) {
if (err) {
res.json({
success: false,
message: 'contact your system administrator. pushToken not saved'
});
} else {
// return the information including token as JSON
res.json({
success: true,
message: 'Welcome aboard!',
token: token,
userRoleID: user.userRoleID,
userRoleName: user.userRoleName,
userPrivilegeID: user.userPrivilegeID,
userPrivilegeName: user.userPrivilegeName,
firstName: user.firstName,
lastName: user.lastName,
email: user.email
});
}
});
}
}
});
}
else { //run SMECS EJS
models.Users.findOne({email: req.body.email.toLowerCase()}, function (err, user) {
if (!user || user.softDeleted !== null) {
//Parent Self Registration Login
models.ParentSelfRegistration.findOne({email: req.body.email.toLowerCase()}, function (err, parentSelfRegistration) {
if (!parentSelfRegistration) {
res.render('login', {error: "ERROR: Incorrect email or pin.", csrfToken: req.csrfToken()});
} else {
if (req.body.pin == parentSelfRegistration.pin) {
req.session.user = parentSelfRegistration;
res.redirect('/parentsSelfRegistration/registerParentStep1');
} else {
res.render('login', {error: "ERROR: Incorrect email or pin.", csrfToken: req.csrfToken()});
}
}
});
//END OF checks for users in UtilityUsers database
} else {
if (bcrypt.compareSync(req.body.pin, user.pin)) { // if user is found and password is right
req.session.user = user;
res.redirect('/dashboard');
//}
} else {
//res.status(400).send('Current password does not match');
res.render('login', {error: "ERROR: Incorrect email or pin.", csrfToken: req.csrfToken()});
//res.render('login', { error: "ERROR: Incorrect email or pin."});
}
}
});
}
};
Here is my ejs.js file:
//Dependencies
var express = require('express');
var routerEjs = express.Router();
var login = require('./authentication/login');
var auth = require('./authentication/auth');
var chooseAlert = require('./alerts/sendingReceiving/1.chooseAlert');
var login = require('./authentication/login');
var csrf = require('csurf');
routerEjs.use(csrf());
/* GET login page. */
routerEjs.get('/login', login.getLogin, function(req, res) {});
routerEjs.post('/login', login.postLogin, function(req, res) {});
routerEjs.get('/logout', login.getLogout, function(req, res) {});
module.exports = routerEjs;
and my api.js file:
//Dependencies
var express = require('express');
var routerApi = express.Router();
var login = require('./authentication/login');
var auth = require('./authentication/auth');
var chooseAlert = require('./alerts/sendingReceiving/1.chooseAlert');
routerApi.post('/login', login.postLogin, function(req, res) {});
routerApi.get('/chooseGroup', auth.auth, chooseAlert.showGroups, function(req, res) {});
routerApi.get('/alerts/sending/chooseAlert', auth.auth, chooseAlert.showAlerts, function(req, res) {});
/* Update pushToken ------------------------------------*/
routerApi.post('/updatePushToken', auth.auth, auth.pin, function(req, res) {});
module.exports = routerApi;
I figured out my problem. I was missing a NULL on my callback...
console.log('1');
async.parallel([
function(callback){
buildAlertButtonsArray.getRealTestAlerts(req,function(arrayAlerts) {
console.log('2');
callback(null, arrayAlerts);
});
},
function(callback) {
if(req.decoded) //API
callback(NULL, 'API');
else //EJS
functions.aclSideMenu(req, res, function (acl) {callback(null, acl);}); //aclPermissions sideMenu
}
],function(err, results){
console.log('3');
})
After log in I want to redirict to /makeitem, which requires a session to open. This works, but after the log in form is submitted I get my error message and I have to refresh to enter the /makeitem. This worked perfectly fine before I started using connect-session-sequelize. The cookie gets stored in db.Sessions right away so that part works.
Why is this happening? Do I have to check for the session somewhere else in my middleware?
How can I make it redirect without any hazzle?
Am I missing something obvious?
Thank you, and please don't just link to docs, I've been looking at docs all day and they make my fairly new programmer brain hurt. I need som love and education.
SERVER.JS
'use strict';
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var _ = require('underscore');
var app = express();
var db = require('./db.js');
// initalize sequelize with session store
var SequelizeStore = require('connect-session-sequelize')(session.Store);
// if heroku use that, else use 3000
var PORT = process.env.PORT || 3000;
app.use(cookieParser());
// Track logins with express session
app.use(session({
secret: 'Magic mike',
resave: true,
saveUninitialized: false,
store: new SequelizeStore({
db: db.sequelize
})
}));
// Make userId available in templates
app.use(function(req, res, next){
res.locals.currentUser = req.session.userId;
next();
});
....
ROUTES/INDEX.JS
var express = require('express');
var router = express.Router();
var _ = require('underscore');
var mid = require('../middleware/');
var db = require('../db.js');
.....
// POST /login
router.post('/login', function(req, res, next) {
var body = _.pick(req.body, 'email', 'password');
if (req.body.email && req.body.password) {
db.user.authenticate(body).then(function(user) {
req.session.userId = user.id;
return res.redirect('makeitem');
});
} else {
var err = new Error('All fields required.');
err.status = 400;
err.message = 'All fields required.';
console.log(err.message);
res.send(err.message);
}
});
.....
// GET /makeitem
router.get('/makeitem', mid.requiresLogin, function(req, res, next) {
var body = _.pick(req.body, 'description', 'amount', 'purchased');
return res.render('makeitem.pug');
});
....
MIDDLEWARE/INDEX.JS
function loggedOut(req, res, next) {
if (req.session && req.session.userId) {
return res.redirect('/makeitem');
} else {
return next();
}
}
function requiresLogin(req, res, next) {
if (req.session && req.session.userId) {
return next();
} else {
var err = new Error('You must be logged in to view this page');
err.status = 401;
return next(err);
}
}
module.exports.loggedOut = loggedOut;
module.exports.requiresLogin = requiresLogin;
My relevant dependencies are:
"express": "^4.14.0"
"express-session": "^1.14.1"
"sequelize": "^3.5.1"
"connect-session-sequelize": "^3.1.0"
"sequelize": "^3.5.1"
"sqlite3": "^3.1.4"
This sounds very similar to the issue :
Race Condition When Used With Passport
Your best way of solving this would be :
router.post('/login', function(req, res, next) {
var body = _.pick(req.body, 'email', 'password');
if (req.body.email && req.body.password) {
db.user.authenticate(body).then(function(user) {
req.session.userId = user.id;
// Add this :
req.session.save(function() {
return res.redirect('makeitem');
});
});
} else {
var err = new Error('All fields required.');
err.status = 400;
err.message = 'All fields required.';
console.log(err.message);
res.send(err.message);
}
});
I am making a user registration form witch insert a record to the mongodb. I am using there fore:
MongoDB version v2.6.11
NodeJS version v0.10.25
Express version 4.13.1
All works fine except when a use a constructor var newUser = new User({...}); it returns the error Object is not a function
The rest works fine. I get the logging before it returns the error but i don't know how to fix this.
users.js
var express = require('express');
var router = express.Router();
var User = require('../models/user');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/Registreren', function(req, res, next) {
res.render('Registration', { title: 'Registreren' });
});
router.get('/Aanmelden', function(req, res, next) {
res.render('Aanmelden', { title: 'Aanmelden' });
});
router.post('/Registreren', function(req, res, next){
// Get form value
console.log('Bericht in behandeling ...')
var username = req.body.username;
var email = req.body.email;
var password = req.body.password;
var password_confirm = req.body.password_confirm;
console.log('username: ' + username);
console.log('email: ' + email);
console.log('password: ' + password);
console.log('password_confirm: ' + password_confirm);
console.log('FIRST TEST: ' + JSON.stringify(req.file));
console.log('SECOND TEST: ' + req.file.profileimage);
console.log('THIRD TEST: ' + req.file.originalname);
// Check for image field
if (req.file || req.file.profileImage){
console.log('Uploading file....');
//File Info
var profileImageOrginalName = req.file.originalname;
var profileImageName = req.file.name;
var profileImageMimetype = req.file.mimetype;
var profileImagePath = req.file.path;
var profileImageExt = req.file.extension;
var profileImageSize = req.file.size;
} else{
console.log('profileImageFile not found....');
// Set default image
var profileImageName = 'noimage.png';
}
// Form validation
req.checkBody('username','Gebruikersnaam is verplicht').notEmpty();
req.checkBody('email','email is verplicht').notEmpty();
req.checkBody('email','email is niet geldig').isEmail();
req.checkBody('username','Gebruikersnaam is verplicht').notEmpty();
req.checkBody('password','Wachtwoord is verplicht').notEmpty();
req.checkBody('password_confirm','Wachtwoorden zijn niet `gelijk').equals(req.body.password);`
// Error handling
var errors = req.validationErrors();
console.log(errors);
if(errors){
console.log('Error handling....');
res.render('Registration',{
errors: errors,
email: email,
username: username,
password: password,
password_confirm: password_confirm
});
} else {
console.log('Make new User ....');
console.log('email: ' + email);
console.log('username: ' + username);
console.log('password: ' + password);
console.log('profileImageName: ' + profileImageOrginalName);
var newUser = new User({
email: email,
username: username,
password: password,
profileimage: profileImageOrginalName
});
console.log('---------------- START TEST----------------------------');
console.log('FIRST TEST: ' + JSON.stringify(newUser));
console.log('SECOND TEST: ' + newUser);
// Create User
User.createUser(newUser, function(err,user){
if(err) throw err;
});
// Succes message
req.flash('succes','Je bent succesvol aangemedld');
res.location('/');
res.redirect('/');
}
});
module.exports = router;
APP.JS
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var methodOverride = require('method-override');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var multer = require('multer');
var flash = require('connect-flash');
var expressValidator = require('express-validator');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// Handle file Uploads
app.use(multer({dest:'./uploads/'}).single('profileimage'));
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//Handle Express Sessions
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
//Passport
app.use(passport.initialize());
app.use(passport.session());
//Vallidator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Flash
app.use(flash());
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
user.js
console.log('Mongoose Start....');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/Users');
var db = mongoose.connection;
db.once('open', function (callback) {
//user Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String,
},
email: {
type: String,
},
profileimage: {
type: String,
}
});
console.log('Create record!');
var User = module.exports = mongoose.model('User',UserSchema);
module.exports.createUser = function(newUser, callback){
newUser.save(callback);
console.log('USER: ' + newUser)
};
});
What i have tried an read
I have read the following post:
Node.js: object is not a function
node.js express.js object is not a function call_non_function
TypeError: object is not a function Node.js
I have tried to build more logging as you can see in the scripts so i can pin point where the problem come from. But i don know how to fix this. I hope you can help me.