Cannot save more than one user to MongoDB - javascript

I am using nodeJS with the expressJS server framework. This issue is regarding passportJS not saving more than 1 user to MongoDB.
Firstly, I set up email registration with passport-local and got that to work fine. Secondly, I set up passport-facebook which essentially broke my email registration somehow. Each registration (email & facebook) now only log in just 1 user, I have to keep deleting the user from mongodb to register again. When there is 1 user in the database and I try to register another - I receive the error below.
process.nextTick(function() { throw err; });
^
TypeError: Cannot read property '1' of null at model.mongodbErrorHandler (/Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose-mongodb-errors/lib/plugin.js:19:49)
at next (/Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/kareem/index.js:145:14)
at Kareem.execPost (/Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/kareem/index.js:193:3)
at /Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/lib/model.js:219:35
at /Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/lib/model.js:152:9
at /Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb/lib/collection.js:524:20
at /Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb/lib/collection.js:658:14
at handleCallback (/Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb/lib/utils.js:95:56)
at /Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb/lib/bulk/unordered.js:465:9
at handleCallback (/Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb/lib/utils.js:95:56)
at resultHandler (/Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb/lib/bulk/unordered.js:413:5)
at /Users/tlr/Dropbox/Websites/app-one/node_modules/mongoose/node_modules/mongodb-core/lib/connection/pool.js:455:18
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
I think the issue may lie around the User Schema because each Strategy saves different user information. Thus, local & facebook may not be marrying up properly in the database which causes an error? Correct me if I'm wrong.
The main files to look at are my userSchema (User.js), my routes file (index.js) where I include my FB Strategy and module imports, and my controller files (userController.js, authController.js) where I export my modules and functions.
User.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
const md5 = require('md5');
const validator = require('validator');
const mongodbErrorHandler = require('mongoose-mongodb-errors');
const passportLocalMongoose = require('passport-local-mongoose');
const userSchema = new Schema({
name: {
type: String,
required: 'Please supply a name',
trim: true,
},
email: {
type: String,
unique: true,
lowercase: true,
trim: true,
required: 'Please supply an email address',
validate: [validator.isEmail, 'Invalid Email Address']
},
id: String,
token: String
});
userSchema.plugin(passportLocalMongoose, { usernameField: 'email' });
userSchema.plugin(mongodbErrorHandler);
module.exports = mongoose.model('User', userSchema);
index.js
const express = require('express');
const mongoose = require('mongoose');
const passport = require('passport');
const User = mongoose.model('User');
const authIDs = require('../../oauth');
const authController = require('../controllers/authController');
const userController = require('../controllers/userController');
const FacebookStrategy = require('passport-facebook').Strategy;
const router = express.Router();
passport.use(new FacebookStrategy({
clientID: authIDs.facebook.clientID,
clientSecret: authIDs.facebook.clientSecret,
callbackURL: authIDs.facebook.callbackURL,
profileFields: ['id', 'emails', 'name'],
passReqToCallback : true
},
function(req, accessToken, refreshToken, profile, done) {
const newUser = new User();
newUser.id = profile.id;
newUser.token = accessToken;
newUser.name = profile.name.givenName;
newUser.email = profile.emails[0].value;
process.nextTick( function() {
User.findOne({id: profile.id}, (err, user) => {
if (err) {
return done(err);
}
if (!user) {
newUser.save().then( user => {
done( null, user );
} ).catch( err => {
done( err );
} );
} else {
return done(null, user);
}
});
});
}
));
router.get( '/login', userController.loginForm);
router.post( '/login', authController.login);
router.get( '/register', userController.registerForm);
router.post( '/register',
userController.validateRegister,
userController.register,
authController.login
);
router.get('/auth/facebook', authController.fbauth);
router.get('/auth/facebook/callback', authController.fbcallback);
router.get( '/logout', authController.logout);
router.get('/', (req, res) => {
res.render('home');
});
module.exports = router;
userController.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
const promisify = require('es6-promisify');
exports.loginForm = (req, res) => {
res.render('login')
};
exports.registerForm = (req, res) => {
res.render('register')
};
exports.validateRegister = (req, res, next) => {
// express validator methods below
req.sanitizeBody('name');
req.checkBody('name', 'You must supply a name!').notEmpty();
req.checkBody('email', 'That email is not valid!').isEmail();
req.sanitizeBody('email').normalizeEmail({
remove_dots: false,
remove_extension: false,
gmail_remove_subaddress: false
});
req.checkBody('password', 'Password cannot be blank!').notEmpty();
req.checkBody('password-confirm', 'Confirmed password cannot be blank!').notEmpty();
req.checkBody('password-confirm', 'Oops! Your passwords do not match').equals(req.body.password);
const errors = req.validationErrors();
if (errors) {
req.flash('error', errors.map(err => err.msg));
res.render('register', { body: req.body, flashes: req.flash() });
return;
}
next();
};
exports.register = async (req, res, next) => {
const user = new User({ name: req.body.name, email: req.body.email});
const register = promisify(User.register, User);
await register(user, req.body.password);
next();
};
authController.js
const passport = require('passport');
const mongoose = require('mongoose');
const User = mongoose.model('User');
exports.login = passport.authenticate('local', {
failureRedirect: '/login',
failureFlash: 'Failed Login!',
successRedirect: '/',
successFlash: 'You are now logged in!'
});
exports.fbauth = passport.authenticate('facebook', {scope: ['email']});
exports.fbcallback = passport.authenticate('facebook', {
failureRedirect: '/login',
failureFlash: 'Failed Login!',
successRedirect: '/',
successFlash: 'You are now logged in!'
});
exports.logout = (req, res, next) => {
req.logout();
req.flash('success', 'You successfully logged out!');
res.redirect('/login')
};
Any suggestions on a fix would be suuuuuuuuper duuuuuuper highly appreciated.

OH MY GOD after hours of trying, like most problems solved in coding, this one was terribly embarrassing.
Because I'm using the code as mentioned in the question above, you can see I'm implementing both a local email registration as well as a passport-facebook authentication. So... What was causing that confusing error was the following code was like this:
passport.serializeUser(User.serializeUser(), function(user, done) {
done(null, user.id);
});
passport.deserializeUser(User.deserializeUser(), function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
instead of simply being like this:
passport.serializeUser(User.serializeUser(), function(user, done) {
done(null, user);
});
passport.deserializeUser(User.deserializeUser(), function(user, done) {
done(null, user);
});

Related

Passport / node.js : Failed to serialize user into session

As a beginner I was following a tutorial to make my first website with node.js but when I try to test a login with 100% valid information I get the following error:
Error: Failed to serialize user into session
Something weird I found is that when the error pops up I go back to the previous page, in this case the login page, and a welcome message I added on /profile.hbs/ pops up as if I was in a session.
This is my passport.js
const res = require('express/lib/response');
const passport = require('passport');
const pool = require('../database');
const router = require('../routes/usuario');
const LocalStrategy = require('passport-local').Strategy;
//const helpers = require('../lib/helpers')
passport.use('local.signin', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, async (req, username, password, done) => {
const rows = await pool.query('SELECT * FROM userr WHERE username = ?', [username])
if (rows.length > 0) {
const user = rows[0];
const validPassword = user.password == password
if (validPassword) {
done(null, user, req.flash('success', 'Bienvenido, ' + user.username))
}else{
done(null, false, req.flash('message', 'ContraseƱa incorrecta'))
}
} else {
return done(null, false, req.flash('message', 'El usuario no existe'))
}
}));
passport.use('local.signup', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, async (req, username, password, done) => {
const newUser = {
username: username,
password: password
};
//newUser.password = await helpers.encryptPassword(password);
const result = await pool.query('INSERT INTO userr SET ?', [newUser])
newUser.id_user = result.insertId;
return done(null, newUser);
}));
passport.serializeUser((user, done) => {
console.log(user)
done(null, user.id_user)
});
passport.deserializeUser(async (id_user, done) => {
const rows = await pool.query('SELECT * FROM userr WHERE ID = ?', [id_user]);
done(null, rows[0]);
});
And this is my authentication.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
const { route } = require('./usuario');
router.get('/signup', (req, res) => {
res.render('auth/signup')
});
router.post('/signup', passport.authenticate('local.signup', {
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true
}));
router.get('/signin', (req, res) => {
res.render('auth/signin')
});
router.post('/signin', (req, res, next) => {
passport.authenticate('local.signin',{
successRedirect: '/profile',
failureRedirect: '/signin',
failureFlash: true
})(req, res, next);
})
router.get('/profile', (req, res) => {
res.render('profile');
});
module.exports = router;
I tried to use a different route, I forced out a session (it worked with a deserialize error I had), I redid the login step with completely different variables and a different database but I still got the same response.

TypeError: User.register is not a function at exports.register in passport-local-mongoose

I was trying to register a user using register function from passport-local-mongoose, but it was not working.
It is showing an error
TypeError: User.register is not a function
at exports.register (....\controllers\userController.js:62:10)
I have put all my controllers in controllers folder, routes ins routes folder and models in models folder.
/modules/User.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
const md5 = require('md5');
const validator = require('validator');
const mongodbErrorHandler = require('mongoose-mongodb-errors');
const passportLocalMongoose = require('passport-local-mongoose');
const userSchema = new Schema({
email: {
type: String,
unique: true,
lowercase: true,
trim: true,
validate: [validator.isEmail, 'Invalid Email Address'],
required: 'Please Supply an email address',
},
name: {
type: String,
required: 'Please supply a name',
trim: true,
},
});
userSchema.plugin(passportLocalMongoose, { usernameField: 'email' });
userSchema.plugin(mongodbErrorHandler);
module.exports = mongoose.model('User', userSchema);
/routes/index.js
const express = require('express');
const router = express.Router();
const storeController = require('../controllers/storeController');
const userController = require('../controllers/userController');
const authController = require('../controllers/authController');
const { catchErrors } = require('../handlers/errorHandlers');
router.get('/', catchErrors(storeController.getStores));
router.get('/stores', catchErrors(storeController.getStores));
router.get('/add', storeController.addStore);
router.post(
'/add',
storeController.upload,
catchErrors(storeController.resize),
catchErrors(storeController.creatStore)
);
router.post(
'/add/:id',
storeController.upload,
catchErrors(storeController.resize),
catchErrors(storeController.updateStore)
);
router.get('/stores/:id/edit', catchErrors(storeController.editStore));
router.get('/store/:slug', catchErrors(storeController.getStoreBySlug));
router.get('/tags/:tag*?', catchErrors(storeController.getStoreByTag));
router.get('/login', userController.loginForm);
router.get('/register', userController.registerForm);
router.post('/register',
userController.validateRegister,
userController.register
);
module.exports = router;
/controllers/userControllers.js
const mongoose = require('mongoose');
const User = mongoose.model('Store');
exports.loginForm = (req, res) => {
res.render('login', { title: 'Login' });
};
exports.registerForm = (req, res) => {
res.render('register', { title: 'Register' });
};
exports.validateRegister = (req, res, next) => {
req.sanitizeBody('name');
req.checkBody('name', 'You must enter a name!').notEmpty();
req.checkBody('email', 'That Email is not valid!').isEmail();
req.sanitizeBody('email').normalizeEmail({
remove_dots: false,
remove_extension: false,
gmail_remove_subaddress: false,
});
req.checkBody('password', 'Password cannot be blank!').notEmpty();
req.checkBody(
'password-confirm',
'Confirmed Password cannot be blank!'
).notEmpty();
req.checkBody(
'password-confirm',
'Oops! Your password do not match'
).equals(req.body.password);
const errors = req.validationErrors();
if (errors) {
req.flash(
'error',
errors.map((err) => err.msg)
);
res.render('register', {
tite: 'Register',
body: req.body,
flashes: req.flash(),
});
return;
}
next();
};
exports.register = (req, res) => {
const user = new User({ email: req.body.email, name: req.body.name });
User.register(user, req.body.password, function (err, user) {
if (err) {
console.log(err);
return res.send('there is some error check your console');
}
res.send('it works');
});
};
I am not able to understand that why User.register is not a function.
I have read many articles and code related to this, in that it was working. But in my project it is not working. Is this because that my Schema, Routes and controllers are in different folder?
In /controllers/userControllers.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
I guess you tried to copy the layout from your other controller named Store.js and forget to rename the file name from which you are importing your modules.
const User = mongoose.model('User',userSchema);
I think you did not provide a schema name i.e userSchema while making the User as a model.

REST API new users not posting to MongoDB

I am new to building REST API's, and I am trying to enter new user information into a collection called 'Users', however, when I submit the information I get Cannot POST /register
Below is my code
server.js
require('dotenv').config()
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const expressValidator = require('express-validator')
mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true , useUnifiedTopology: true })
const db = mongoose.connection
db.on('error', (error) => console.error(error))
db.once('open', () => console.log('Connected to Database'))
app.use(express.json())
const articlesRouter = require('./routes/articles')
app.use('/articles', articlesRouter)
const userRouter = require('./routes/users')
app.use('/register', userRouter)
app.set('view-engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.get('/', (req, res) => {
res.render('index.ejs')
})
app.get('/login', (req, res) => {
res.render('login.ejs')
})
app.post('/login', (req, res) => {
})
app.get('/register', (req, res) => {
res.render('register.ejs')
})
app.listen(3000, () => console.log('Server Started'))
Users model
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
var userSchema = new mongoose.Schema({
firstName: String,
lastName: String,
email: String,
password: String,
permissionLevel: Number,
created: Date},
{ collection: 'Users'});
module.exports = mongoose.model('Users', userSchema);
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.getUserByEmail = function(email, callback){
var query = {email: email};
User.findOne(query, callback);
}
module.exports.getUserById = function(id, callback){
user.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback) {
bcrypt.compare(candidatePassword, hash, function(err, isMatch){
if(err) throw err;
callback(null, isMatch)
});
}
users routes
const express = require('express')
const router = express.Router()
const Users = require('../models/users')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
//Register Page - GET
router.get('/register', (req, res) => {
res.render('register.hbs', {
pageTitle: 'register'
});
});
//Login Page - GET
router.get('/login', (req, res) => {
res.render('login.hbs', {
pageTitle: 'login'
});
});
//Register - POST
router.post('/', (req, res) => {
var firstName = req.body.firstName;
var lastName = req.body.lastName;
var email = req.body.email;
var password = req.body.password;
//validations
req.checkBody('firstName', 'Your First Name is Required').notEmpty();
req.checkBody('lastName', 'Your Last Name is Required').notEmpty();
req.checkBody('email', 'A valid email is required').isEmail();
req.checkBody('password', 'An Account Passowrd Is Required').notEmpty();
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors:errors
});
} else {
var newUser = new newUser({
firstName: firstName,
lastName: lastName,
email: email,
password: password,
});
User.createUser(newUser, function(err, user) {
if(err) throw(err);
console.log(user);
});
req.flash('success_message', "You are now registered!");
res.redirect('/login');
}
});
passport.use(new LocalStrategy({
email: 'email'
},
function(email, password, done){
Users.getUserByEmail(email, function(err, Users){
if(err) throw err;
if(!Users){
return done(null, false, {message: 'Unknown Email Address'});
}
Users.comparePassword(password, user.password, function(err, ismatch){
if(err) throw err;
if(ismatch){
return done (null, user);
} else {
return done(null, false, {message: 'Invalid Passowrd'});
}
});
});
}));
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
Users.getUserByID(id, function(err, user) {
done(err, user)
});
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/login',
successFlash: 'Welcome',
failureFlash: 'Invalid Email or Passowrd!'
}), function(req, res) {
res.redirect('/');
});
router.get('/logout', function(req, res) {
req.logout();
req.flash('Success_message', 'You are now logged out!')
res.redirect('/');
});
module.exports = router
I suspect the conflict is between the router /register and the my 'Users' collection. I'm just unable to pinpoint what the issue could be.
Any help would be greatly appreciated
Your userRouter is mounted on /users (from your code: app.use('/users', userRouter), meaning that all the routes you declared in the router are prefixed by /users).
Try calling POST /users/register.
You're using users routes file at /users route, so when you declare /register route in users routes file it become /users/register please send your REST API request to /users/register endpoint

MEAN App error expected object

I am trying to code a mean authentication app. Right now i can create user in mongodb via postman but when i try to authenticate it,if it has wrong username or password it gives proper feedback,wrong password etc, but if it matches correct username and password on database, server shutdowns, it doesnt gives any feedback on postman and it gives the following error on server terminal:
(node:11262) DeprecationWarning: Mongoose: mpromise (mongoose's
default promise library) is deprecated, plug in your own promise
library instead: http://mongoosejs.com/docs/promises.html
/home/cagdas/Desktop/basictest/node_modules/jsonwebtoken/sign.js:90
throw err;
^
Error: Expected object
at validate
(/home/cagdas/Desktop/basictest/node_modules/jsonwebtoken
/sign.js:35:11) at Object.module.exports [as sign]
(/home/cagdas/Desktop/basictest/node_modules/jsonwebtoken
/sign.js:101:7) at User.comparePassword
(/home/cagdas/Desktop/basictest/routes/users.js:40:26)
at bcrypt.compare (/home/cagdas/Desktop/basictest/models/user.js:52:6)
at
/home/cagdas/Desktop/basictest/node_modules/bcryptjs/dist
/bcrypt.js:297:21
at /home/cagdas/Desktop/basictest/node_modules
/bcryptjs/dist/bcrypt.js:1353:21
at Immediate.next (/home/cagdas/Desktop/basictest/node_modules
/bcryptjs/dist/bcrypt.js:1233:21)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
This is my code:
app.js:
const express = require('express') ;
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');
const mongoose = require('mongoose');
const config = require('./config/database');
// Connect to Database
mongoose.connect(config.database, { useMongoClient: true });
// On Connection
mongoose.connection.on('connected', () => {
console.log('Connected to database '+config.database);
});
// On Error
mongoose.connection.on('error', (err) =>{
console.log('Database error: '+err);
});
const app = express();
const users = require('./routes/users');
// Port Number
const port = 3000;
// Cors Middleware
app.use(cors());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
// Body Parser Middleware
app.use(bodyParser.json());
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.use('/users', users);
// Index Route
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
// Start Server
app.listen(port, () => {
console.log('Server started on port '+port);
});
users.js:
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
const User = require('../models/user');
const config = require('../config/database');
// Register
router.post('/register', (req, res, next) => {
let newUser = new User({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.password
});
User.addUser(newUser, (err, user) =>{
if(err){
res.json({success: false, msg:'Failed to register user'});
} else {
res.json({success: true, msg:'User registered'});
}
});
});
// Authenticate
router.post('/authenticate', (req, res, next) => {
const username = req.body.username;
const password = req.body.password;
User.getUserByUsername(username, (err, user) => {
if(err) throw err;
if(!user){
return res.json({success: false, msg: 'User not found'});
}
User.comparePassword(password, user.password, (err, isMatch) => {
if(err) throw err;
if(isMatch){
const token = jwt.sign(user, config.secret, {
expiresIn: 86400 // 1 day
});
res.json({
success: true,
token: 'JWT ' +token,
user: {
id: user._id,
name: user.name,
username: user.username,
email: user.email
}
});
} else {
return res.json({success: false, msg: 'Wrong Password'});
}
});
})
});
// Profile
router.get('/profile', (req, res, next) => {
res.send('PROFILE');
});
module.exports = router;
database.js:
module.exports = {
database: 'mongodb://localhost:27017/basictest',
secret: '123456789'
}
user.js:
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config =require('../config/database');
// User Schema
const UserSchema = mongoose.Schema({
name: {
type: String
},
email: {
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const User = module.exports = mongoose.model('User', UserSchema);
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
const query = {username: username}
User.findOne(query, callback);
}
module.exports.addUser = function(newUser, callback){
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.comparePassword = function(candidatePassword, hash,
callback){
bcrypt.compare(candidatePassword, hash, (err, isMatch) => {
if(err) throw err;
callback(null, isMatch);
});
}
passport.js
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/user');
const config = require('../config/database');
module.exports = function(passport){
let opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
User.getUserById(jwt_payload._id, (err, user) => {
if(err){
return done (err, false);
}
if(user){
return done(null, user);
} else {
return done(null, false);
}
});
}));
}
Solution - not user only { data: user }
const token = jwt.sign({data: user}, config.secret, {
expiresIn: 604800 // 1 week
});
Got the same error for a while and I suggest that you recreate a new object user (without the hashed password for security reason) and insert it into the sign function.
let restrictedUser = {
id: user._id,
username: user.username,
name: user.name,
email: user.email
}
const token = jwt.sign(restrictedUser, config.secret, {
expiresIn: "7d"
})
Hope this will help.
Not sure about this, But you can try this
"npm remove mongoose"
Then
"npm install mongoose#4.10.8 --save"
Hope it will help you..
Thanks...

"TypeError: User is not a constructor " while sending object to server in node.js

I am trying to save a user to mongodb database using post request as follow, but I got the error TypeError: User is not a constructor. It's a pretty simple set up of the code but i can't figure out anything wrong with it.
//models/users.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const confic = require('../models/users');
// User schema
const UserSchema = mongoose.Schema({
name: {
type: String,
},
email: {
type: String,
required: true
},
username:{
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const User = module.exports = mongoose.model('User', UserSchema);
module.exports.getUserById = function(id,callback){
User.findById(id,callback);
}
module.exports.getUserByUsername = function(username,callback){
const query = {username:username}
User.findOne(query,callback);
}
module.exports.addUser= function (newUser, callback) {
bcrypt.gensalt(10,(err,salt) => {
bcrypt.hash(newUser.password, salt , (err, hash) =>{
if(err) throw err;
newUser.password=hash;
newUser.save(callback);
});
});
}
routes/users.js
//routes/users.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
User = require('../models/users');
// // Register
router.post('/register', (req, res, next) => {
var newUser = new User({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.password
});
User.addUser(newUser, (err, User) => {
if(err){
res.json({success: false, msg:'Failed to register user'});
} else {
res.json({success: true, msg:'User registered'});
}
});
});
// Authenticate
router.post('/authenticate', (req, res, next) => {
res.send('AUTHENTICATE');
});
// Profile
router.get('/profile', (req, res, next) => {
res.send('PROFILE');
});
module.exports = router;
I am using Postman chrome to send data but it is not showing user registered according to program.
You are exporting your user model from a different file and trying to import from a different file.
change this line:
const User = require('../config/database');
to this:
const User = require('../models/users') # import your user model

Categories

Resources