Save with Mongoose - javascript

I try to simply save a new User in my mongodb base into a controller file :
var mongoose = require('mongoose');
var UserModel = mongoose.model('User');
// signup
exports.create = function (req, res) {
console.log(req.body);
var user = new UserModel({
username: req.body.username,
password: req.body.password,
email: req.body.email
});
user.save(function (err) {
if (!err) {
return console.log("created");
}
else {
return console.log(err);
}
});
}
In debug mode, I can see that user.save() is not executed without error...
I don't know why because I get correct value in username / password / email field.
Here my model file :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var objectId = Schema.ObjectId;
var userSchema = mongoose.Schema({
username: String,
password: String,
email: String
});
var userModel = mongoose.model('User', userSchema);
EDIT :
In my app.js I have the connection to mongodb :
mongoose.connect('mongodb://localhost/mydb', function(err){
if(err) {
console.log(err);
}
});
var userModel = require('./models/user'),
userController = require('./controllers/users');

I grouped all (controller + model) in one file to test :
var express = require('express')
, routes = require('./routes')
, userRoute = require('./routes/user')
, http = require('http')
, path = require('path')
, io = require('socket.io')
, mongoose = require('mongoose');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
mongoose.connect('mongodb://127.0.0.1/mydb', function(err){
if(err) {
console.log(err);
}
else {
console.log("Connected to mongo DB")
}
});
/*var userModel = require('./models/user'),
tchatMessageModel = require('./models/tchatMessage'),
userController = require('./controllers/users'),
tchatMessageController = require('./controllers/tchatMessages'); */
app.get('/', routes.index);
app.get('/signup', userRoute.signup);
app.get('/signin', userRoute.signin);
//app.post('/signup', userController.create);
//app.get('/users', userRoute.list);
var Schema = mongoose.Schema;
var userSchema = Schema({
username: String,
password: String,
email: String
});
var UserModel = mongoose.model('User', userSchema);
app.post('/signup', function (req, res) {
console.log(req.body);
var user = new UserModel({
username: req.body.username,
password: req.body.password,
email: req.body.email
});
user.save(function (err) {
if (!err) {
return console.log("created");
}
else {
return console.log(err);
}
});
});
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
And I get the same issue... don't understand. Maybe issue in Express configuration ?
EDIT :
Issue solved with :
app.js
mongoose.model("User", require("./models/user").userModel);
model.js
exports.userModel = userSchema;

You should use keyword "new", when you are creating a mongoose Schema:
var userSchema = new mongoose.Schema({
/*...*/
});

Related

Express APP how to redirect user to /:id path from server side

I'm learning Node.js and I'm finding some troubles with redirecting the user to an :id path. I would like to print there his username.
So to make an overview it is a landing page with a form where I ask for an Alias and an email. When user clicks submit I'd like to move him to /:id path to print its' username.
My code is the following:
var express = require("express"),
app = express(),
request = require("request"),
mongoose = require("mongoose"),
bodyParser = require("body-parser");
app.set("view engine", "ejs")
app.use(express.static("public"));
app.use(bodyParser.urlencoded({extended: true}));
mongoose.connect("mongodb://localhost/Scape_Room", {useNewUrlParser: true, useUnifiedTopology: true});
var userSchema = new mongoose.Schema({
email: String,
alias: String,
});
var user = mongoose.model ("user",userSchema);
app.get("/", function(req, res){
res.render("index")
})
app.post("/newuser", function(req,res){
var name = req.body.name;
var email = req.body.email;
var newUser = {name:name, email:email}
user.create(newUser, function(err,newlyUser){
if(err){
console.log(err)
} else {
res.redirect("/start/:id")
}
})
})
app.get("/start/:id", function(req,res){
user.findById(req.params.id, function(err, foundUser){
if(err){
console.log(err)
} else{
res.render("startPoint", {user:foundUser})
}
})
})
app.listen(3000, function(err){
console.log("Server listening")
})
error is the following: { CastError: Cast to ObjectId failed for value ":id" at path "_id" for model "user"
I've tried:
- to change the path to :_id
- added start/ into the route
When you are using the redirect() method, you must pass a real route url not an id.
const express = require("express")
const request = require("request");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const app = express();
app.set("view engine", "ejs")
app.use(express.static("public"));
mongoose.connect("mongodb://localhost/Scape_Room", { useNewUrlParser: true, useUnifiedTopology: true });
const userSchema = new mongoose.Schema({
email: String,
alias: String,
});
const user = mongoose.model("user", userSchema);
app.get("/", function (req, res) {
res.render("index");
});
app.post("/newuser", function (req, res) {
const { name, email } = req.body;
if (!name || !email) {
return res.end();
}
const newUser = { name: name, email: email }
user.create(newUser, function (err, newlyUser) {
if (err) {
console.log(err);
return res.end();
}
if (!newlyUser) {
console.log("Couldn't save user!");
return res.end();
}
if (!newlyUser.id) {
console.log("No user id found");
return res.end();
}
res.redirect(`/start/${newlyUser.id}`);
});
});
app.get("/start/:id", function (req, res) {
user.findById(req.params.id, function (err, user) {
if (err) {
console.log(err);
} else {
res.render("startPoint", { user });
}
})
})
app.listen(3000, function (err) {
console.log("Server listening")
});
Use something like below
app.post("/newuser", function(req,res){
var name = req.body.name;
var email = req.body.email;
var newUser = {name:name, email:email}
user.create(newUser, function(err,newlyUser){
if(err){
console.log(err)
} else {
res.redirect(`/start/${newlyUser._id}`)
}
})
})

Mongoose Multiple Databases TypeError: users.model is not a function

I am trying to use Mongoose's example for defining models in a separate document from their schemas (whilst having multiple databases).
Mongoose's Docs example for User.js:
const userSchema = require('./userSchema');
module.exports = conn => {
conn.model('User', userSchema);
};
However, I am getting errors
(TypeError: users.model is not a function)
that I suspect come from the database promise that mongoose.createConnection(...)..
The structure is as followed
-models
-user.js
-schemas
-userSchema.js
-app.js
I have cut information that I don't think is apart of the problem (noted ...) but let me know if I need to include anything else.
App.js:
...
var cookieParser = require('cookie-parser');
var session = require('express-session');
var mongoose = require('mongoose');
var logger = require('morgan');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var indexRouter = require('./routes/index');
var generatorRouter = require('./routes/generator');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
// connect databases
var users = mongoose.createConnection('mongodb://localhost:27017/users', {useNewUrlParser: true, useUnifiedTopology: true})
.then(function() {
console.log('usersDB connected')
}).catch(err => console.log(err))
var userData = mongoose.createConnection('mongodb://localhost:27017/userData', {useNewUrlParser: true, useUnifiedTopology: true})
.then(() => console.log('userDataDB connected'))
.catch(err => console.log(err))
app.set('trust proxy', 1)
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(session({
secret: shhhhh,
resave: false,
saveUninitialized: true
}));
//set up passport
app.use(passport.initialize());
app.use(passport.session());
var User = require('./models/user')(users);
app.use('/', indexRouter);
app.use('/g', generatorRouter);
app.use('/users', usersRouter);
passport.use(
new LocalStrategy(function(username, password, done) {
console.log(User);
User.findOne({
username: username
}, function(err, user) {
if (err) return done(err);
if (!user) return done(null, false);
if (!user.authenticate(password)) return done(null, false);
return done(null, user);
});
})
);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
...
module.exports = app;
user.js
var userSchema = require('../schemas/userSchema');
module.exports = users => {
users.model('User', userSchema);
};
userSchema.js
var mongoose = require('mongoose');
var bcrypt = require('bcrypt')
var userSchema = new mongoose.Schema({
"email": {
type: String,
required: true
},
"username": {
type: String,
required: true
},
"password": {
type: String,
required: true
},
"date": {
type: Date,
default: Date.now
},
})
//generate hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8));
};
// password checker
userSchema.methods.authenticate = function(password) {
return bcrypt.compareSync(password, this.password);
};
module.exports = userSchema;
I've also tried using User(users) and User(await users) but neither works for trying to pass the database into the User function.
your user.js is incorrect. You cannot use users.model('User', userSchema);
it should be like this
var userSchema = require('../schemas/userSchema');
var mongoose = require('mongoose');
module.exports = () => {
mongoose.model('User', userSchema);
};
i think the problem is in user.js file, the model function comes from mongoose so you need to create instance of mongoose and use it to create the model by .model()
so the rewrite of the code will be something like this
var mongoose = require('mongoose');
var userSchema = require('../schemas/userSchema');
module.exports = users => {
mongoose.model('User', userSchema);
};
i hope it works

Node.js Express.js MongoDB: route.post() requires callback functions but got a [object Undefined]

I am trying to set up a MEAN (mongodb, express, nodejs, angular6(CLI)) app. Trying to post user signup form data to mongo database, but its throwing an error. It is my first MEAN app, trying to learn.
Do I miss something here?
Error: Route.post() requires callback functions but got a [object Undefined]
server.js
Here is server.js file.
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var http = require('http');
var app = express();
var api = require('./server/routes/api');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(express.static(path.join(__dirname + '/dist/meanshopcart')));
app.use('/api', api);
app.post('/sign-up', api.signup);
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, '/dist/meanshopcart/index.html'));
});
var port = process.env.PORT || '3000';
app.set('port', port);
var server = http.createServer(app);
//app.listen(port, function(){
// console.log("Server is running..!!");
//});
server.listen(port, function(err){
if(err){
return console.log('something bad happened', err);
}
console.log("Server is running..!!");
});
Routes Folder(routes/api.js)
my routes folder ./server/routes/api.js
var express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const User = require('../models/users');
const db = 'mongodb://localhost:27017/meanshopapp';
mongoose.connect(db, function(err){
console.log("mongo connection done");
if(err){
console.log("Error.."+err);
}
});
router.get('/', (req, res)=>{
console.log("get api ");
User.find({}, function(err, users) {
if (err) throw err;
// object of all the users
console.log(users);
});
res.send(users);
});
exports.signup = function(req, res, next){
console.log("new user entered");
var newUser = new User();
newUser.name = req.body.name;
newUser.email = req.body.email;
newUser.password = req.body.password;
newUser.phoneNo = req.body.phone;
newUser.address = req.body.address;
newUser.save(function(err){
if(err){
console.log("error saving user");
}
else{
console.log("user inserted");
}
})
};
module.exports = router;
Model
this is my user schema user.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name : { type: String },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
phoneNo: { type: Number },
address: { type: String }
});
module.exports = mongoose.model('user', userSchema, 'users');
You are using exports and module.exports.
Either you should follow #dimagolovin's answer
OR
module.exports = {router};
and use
`app.use('/api', api.router);
app.post('/sign-up', api.signup);`
Try to change the follwing in ./server/routes/api.js
function signup(req, res, next){
console.log("new user entered");
var newUser = new User();
newUser.name = req.body.name;
newUser.email = req.body.email;
newUser.password = req.body.password;
newUser.phoneNo = req.body.phone;
newUser.address = req.body.address;
newUser.save(function(err){
if(err){
console.log("error saving user");
}
else{
console.log("user inserted");
}
})
};
module.exports = {router, signup};
It should do the work

uploading file to folder in node-express site using multer with mongodb

I have a node-express app that authenticates user data and upload files using multer, when i click on submit, the name, email, username and password fields are stored in the mongodb database. But the profileimage file is not stored in the uploads folder nor stored by monogdb. I tried using some help i found online but all worked with my app but did not store the picture in the folder nor did mongodb pass the profileimage field in the cli as expected by the model i used. Please What am I not getting right here, that's stopping the file from being uploaded and stored in the required folder and the name of the file being displayed in the mongodb cli?
Note: Other codes that worked fine with my app are commented in the below code sample but none stored the picture in the desired folder.
users.js
var express = require('express');
var router = express.Router();
var multer = require('multer');
var uploads = multer({dest: './uploads/'});
/*var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var originalname = file.originalname;
var extension = originalname.split(".");
filename = Date.now() + '.' + extension[extension.length-1];
cb(null, filename);
}
}); */
//Require a model page
var User = require('../models/user');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register', function(req, res, next) {
res.render('register', {
'title': 'Register'
});
});
router.get('/login', function(req, res, next) {
res.render('login', {
'title': 'Log In'
});
});
//router.post('/register', multer({storage: storage, dest: './uploads/'}).single('profileimage'), function(req,res){
router.post('/register', uploads.single('profileimage'), function(req,res,next){
//Get Form Value
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
//Check for Image field
if(req.file){
console.log('uploading File...');
// File Info
var profileImageOriginalName = req.files.profileimage.originalname;
var profileImageName = req.files.profileimage.name;
var profileImageMime = req.files.profileimage.mimetype;
var profileImagePath = req.files.profileimage.path;
var profileImageExt = req.files.profileimage.extension;
var profileImageSize = req.files.profileimage.size;
} else {
// Set a Default Image
var profileImageName = 'noimage.png';
}
/*if(req.file){
console.log('uploading File...');
// File Info
originalname = req.files.profileimage.originalname;
feildname = req.files.profileimage.fieldname;
mimetype = req.files.profileimage.mimetype;
path = req.files.profileimage.path;
encoding = req.files.profileimage.encoding;
size = req.files.profileimage.size;
} else {
// Set a Default Image
var original = 'noimage.png';
} */
//Form Validation
req.checkBody('name', 'Name Field is required').notEmpty();
req.checkBody('email', 'Email Field is required').notEmpty();
req.checkBody('email', 'Email not valid').isEmail();
req.checkBody('username', 'Username Field is required').notEmpty();
req.checkBody('password', 'Password Field is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
//Check for Errors
var errors = req.validationErrors();
if(errors){
res.render('register',{
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileImage: profileImageName
});
//Create User
User.createUser(newUser, function (err, user) {
if(err) throw err;
console.log(user);
});
//Success Message
req.flash('success', 'You are now registered and may Log in');
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 expressValidator = require('express-validator');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
//var multer = require('multer');
var flash = require('connect-flash');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var multer = require('multer');
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
var upload = multer({ dest: './uploads' });
// 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());
// Validator
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')));
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
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;
models/user.js
var mongoose = require('mongoose');
//This chooses the database to use for storing data a very important step
mongoose.connect('mongodb://localhost/nodeauth');
var db = mongoose.connection;
//User Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
profileimaage: {
type: String
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function (newUser, callback) {
newUser.save(callback);
}
create multerhelper.js file in your app nd add below code in it
const multer = require('multer');
// const fs = require('fs');
let fs = require('fs-extra');
let storage = multer.diskStorage({
destination: function (req, file, cb) {
let Id = req.body.id;
let path = `tmp/daily_gasoline_report/${Id}`;
fs.mkdirsSync(path);
cb(null, path);
},
filename: function (req, file, cb) {
// console.log(file);
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, file.fieldname + '-' + Date.now() + "." + extension);
}
})
var upload = multer({ storage: storage });
let createUserImage = upload.single('images');
let multerHelper = {
createUserImage,
}
module.exports = multerHelper;
in your user.js file import this file
const multerhelper = require("../multerhelper.js");
router.post('/register',multerhelper , function(req,res,next){
Here you are just loading the multer module not using anywhere.
Check the link for full uses :
https://github.com/expressjs/multer

Define mongoose and Schema only ones

Hi i am developing nodejs application with express and mongodb.So i must define mongoose and schema in my all routing js to use mongo and schema. I want to define them only ones. I am new at node.js so please be patient. My project structure:
My route.js is shown below:
var routes = function (app) {
app.locals.error=null;
app.get('/login', function (req, res) {
return res.render(__dirname + "/views/login", {
title: 'Giriş',
stylesheet: 'login'
});
});
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/fuatblog");
var UserSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
age: Number
}),
Users = mongoose.model('Users', UserSchema);
app.post('/sessions', function (req, res) {
console.log(req.body.login.email);
console.log(req.body.login.password);
console.log(req.body.login.rememberMe);
Users.find({
email: req.body.login.email,
password: req.body.login.password
}, function (err, docs) {
if (! docs.length) {
// no results...
console.log('User Not Found');
res.status(400);
return res.render(__dirname + "/views/login", {
title: 'Giriş',
stylesheet: 'login',
error: 'Kullanıcı adı veya şifre yanlış'
});
}
console.log('User found');
req.session.email = docs[0].email;
console.log(req.session.email);
return res.redirect('/Management');
});
});
};
module.exports = routes;
And my server.js(app.js)
/**
* Module dependencies.
*/
////Mongoose eklendi
var express = require('express'),
mongoose= require('mongoose');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
////Cookie için eklendi.
app.use(express.cookieParser());
////Session desteği için eklendi
app.use(express.session({secret: 'asdfsdfsafasdfasdfasdf'}));
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
////Put ve Delete mothodları için
app.use(express.methodOverride());
////Requeestleri ayrıştırmak için kullanılıyor
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
////Helpers
//require('./apps/helpers')(app);
//Routes
require('./apps/authentication/routes')(app)
require('./apps/blog/routes')(app)
require('./apps/management/routes')(app)
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
I'm going to assume that you meant that you want to define the Schema only ONCE.
What I like to do is to initialize all the models that I'm going to use when the server starts and the mongodb connection is established.
An ideal directory structure would be something like this:
mongodb
--schemas
----user.js
--models.js
You would put your schemas inside the schema folder, such as your User model:
(user.js)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = function() {
var UserSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
age: Number
});
mongoose.model("User", UserSchema);
};
In models.js, you would have code that initializes each schema model in the schemas directory.
(models.js)
exports.initialize = function() {
require("fs").readdirSync(__dirname + "/schemas").forEach(function(file) {
require('./schemas/' + file)();
});
};
In your app.js file, you would do this call to initialize all your schemas AFTER you establish your connection to mongoose:
require($pathToYourModelsJsFile).initialize();
After this, you are all set to use your models! All you have to do for when you want to use them is:
var mongoose = require('mongoose');
var User = mongoose.model('User');
// Do work
User.find();

Categories