Why is this error displaying 'Illegal arguments: undefined, string'? - javascript

I am building a simple node.js app. I build my backend api for user registration. I am trying to test it with postman and i am having this error 'Illegal arguments: undefined, string'. What could be responsible for this?. Relevant codes are supplied below
User Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema
const UserSchema = new Schema({
userName: {
type: String,
required: true,
unique: true
},
firstName: {
type: String,
},
lastName: {
type: String,
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
dateOfRegistration: {
type: Date,
default: Date.now
},
dateOfBirth: {
type: Date,
},
userCategory: {
type: String,
default: 'workingClass'
}
})
module.exports = mongoose.model('users', UserSchema)

The problem has been solved. Postman was sending the request as in 'text' format instead of 'JSON' format and as such the backend couldn't make sense of data. Every worked fine when changed the settings on my Postman from 'text' to 'JSON'.

controller
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const auth = require('../middleware/auth')
const { check, validationResult } = require('express-validator');
const User = require('../models/User');
const UserModel = require('../models/User');
// #route POST api/users, Register a users; access Public
router.post('/', [
check('userName', 'Please add user name').not().isEmpty(),
check('email', 'Please include a valid email').isEmail(),
check('password', 'Please enter a password with six or more characters').isLength({ min: 5 })
],
async (req, res) => {
const errors = validationResult(req);
if(!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { userName, firstName, lastName, email, password, dateOfBirth, dateOfRegistration, userCategory } = req.body;
try {
let user = await User.findOne( { email });
if (user) {
return res.status(400).json({ msg: 'User already exist'})
}
user = new User({
userName,
firstName,
lastName,
email,
password,
dateOfBirth,
dateOfRegistration,
userCategory
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
const payload = {
user: {
id: user.id
}
}
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error')
}
}
);
module.exports = router;
server.js
const express = require('express');
const mongoose = require('mongoose');
const path = require('path');
// api require routes
const users = require('./routes/users');
// const auth = require('./routes/auth');
// const students = require('./routes/studentsSub');
// const workers = require('./routes/workersSub');
const app = express();
// database connection
const connectDB = async () => {
try {
await mongoose.connect('mongodb+srv://nawill:usha0816#cluster0.77u0d.mongodb.net/myFirstDatabase?retryWrites=true&w=majority',
{
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
});
console.log('MongoDB Connected ...')
} catch (err) {
console.error(err.message);
process.exit(1);
}
};
connectDB();
//Middleware
app.use(express.json({ extended: false }));
// app.get('/', (req, res) => res.json ({ msg: 'Hello node project'}));
//Routes
app.use('/api/users', users );
// app.use('/api/auth', auth );
// app.use('/api/students', students );
// app.use('/api/workers', workers );
//Start Server
app.listen(3000, ()=> console.log("Server started on 3000"))

Related

sending request to postman and it is giving an error

I am trying to send the request to postman but it is giving me an error.The nodemon is working and the server is running in the terminal
index.server.js file
//jshint esversion:6
const express = require("express");
const env = require("dotenv");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
//routes
const userRoutes = require('./routes/user');
env.config();
mongoose.connect(`mongodb+srv://${process.env.MONGO_DB_USER}:${process.env.MONGO_DB_PASSWORD}#cluster0.igfgf61.mongodb.net/${process.env.MONGO_DB_DATABASE}?retryWrites=true&w=majority`,{
// useNewUrlParser: true,
// useUnifiedTopology:true,
// useCreateIndex : true
}).then(() => {
console.log("database connected");
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('./api/', userRoutes);
app.listen(process.env.PORT, () => {
console.log(`server is running successfully on ${process.env.PORT}`);
});
routes/user.js file
//jshint esversion:6
const express = require("express");
const { signup } = require("../controller/user");
const router = express.Router();
router.post('/signup', signup);
router.post('/signin', (req, res) => {
});
module.exports = router
models/user.js file
//jshint esversion:6
const mongoose = require("mongoose");
const bcrypt = require('bcrypt');
const userSchema = new mongoose.Schema(
{
firstName: {
type: String,
required: true,
trim: true,
min: 3,
max: 20
},
lastName: {
type: String,
required: true,
trim: true,
min: 3,
max: 20
},
username: {
type: String,
required: true,
trim: true,
unique: true,
index: true,
lowercase: true
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true
},
hash_password: {
type: String,
required: true,
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user'
},
contactNumber: {type: String},
profilePicture: {type: String},
}
,{timestamps: true});
userSchema.virtual('password')
.set(function(password){
this.hash_password=bcrypt.hashSync(password, 10);
});
userSchema.methods= {
authenticate: function(password){
return bcrypt.compareSync(password, this.hash_password);
}
}
module.exports = mongoose.model('User', userSchema);
controller/user.js file
//jshint esversion:6
const User = require("../models/user");
exports.signup =(req, res) => {
User.findOne({email: req.body.email})
.exec((error, user) => {
if(user) return res.status(400).json({
message: 'user already registered'
});
const {
firstName,
lastName,
email,
password
} =req.body;
const _user = new User({
firstName,
lastName,
email,
password,
username: Math.random().toString()
});
_user.save((error, data) => {
if(error){
return res.status(400).json({
message: 'something went wrong'
});
}
if(data){
return res.status(201).json({
message: 'user created succesfully'
});
}
});
});
}
when i am trying to post request it is giving me an error. what should i do?
this is the request i made in postman and it is giving me an error(https://i.stack.imgur.com/Qsn5V.png)
In your index.server.js instead of "./api/" use "/api"
app.use("/api", userRoutes)

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.

node.js req.body returning undefined

EDIT: #LawrenceCherone solved this, its (req, res, next) not (err, res, req)
I am creating a MERN app (Mongo, express, react, node).
I have some routes that work fine and return data from mongodb. However I created a new controller to access a separate collection and whenever i try to create a new document in it my req.body returns undefined.
I have setup my server.js like this:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const connectDB = require("./db");
const app = express();
const apiPort = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.use(bodyParser.json());
connectDB();
app.use("/api", require("./routes/router"));
var server = app.listen(apiPort, () => console.log(`Server running on port ${apiPort}`));
module.exports = server;
My router looks like this:
const express = require("express");
const QuizController = require("../controllers/quiz-controller");
const UserController = require("../controllers/user-controller");
const router = express.Router();
// quiz routes
router.post("/quizzes", QuizController.createQuestion);
router.get("/quizzes", QuizController.getAllQuestions);
router.get("/quizzes/:quiz_name", QuizController.getQuestionsByQuiz);
router.get("/quizzes/questions/:question_id", QuizController.getQuestionById);
router.put("/quizzes/:question_id/edit", QuizController.updateQuestionById);
router.delete("/quizzes/:question_id", QuizController.deleteQuestionById);
// user routes
router.post("/users", UserController.createUser);
module.exports = router;
All of the /quizzes routes work perfectly fine and i have had no trouble accessing the body. The UserController.createUser method is almost identical to Quizcontroller.createQuestion too so I am very confused.
Here is the user-controller with the createUser function:
const User = require("../models/User");
createUser = async (err, res, req) => {
const body = req.body;
console.log(req.body);
console.log(req.params);
console.log(body);
if (!body) {
return res.status(400).json({
succes: false,
error: "You must provide a body",
});
}
try {
const newUser = new User(body);
console.log(newUser);
if (!newUser) {
return res.status(400).json({ success: false, error: err });
}
const user = await newUser.save();
return res
.status(200)
.json({ success: true, newUser: user, msg: "New user created" });
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
};
module.exports = { createUser };
Here is an image of the postman request I am using to try test this:
[1]: https://i.stack.imgur.com/UHAK5.png
And the user model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true,
},
emailAddress: {
type: String,
required: true,
},
permission: {
type: String,
required: true,
},
auth0Id: {
type: String,
required: true,
},
});
module.exports = mongoose.model("users", UserSchema);
The functional parameter order matters.
its
createUser = async (req, res, next) => // correct format
Not
createUser = async (err, res, req) // wrong format

Postman returns ' Could not get any response '

Postman returns ' Could not get any response ' when I send a Post request, but get a request to other URL works just fine. please how can I resolve this issue? index.js is the entry point to my application. the get URL below is working.
index.js
const express = require('express')
const mongoose = require('mongoose')
const dotenv = require('dotenv')
const bodyParser = require('body-parser')
const app= express()
//body parser
app.use(bodyParser.json())
//config
dotenv.config()
//connect to db
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
()=>{
console.log('contented to db')
}
)
//import route
const authRoute = require('./ROUTES/auth')
app.use('', authRoute)
app.use('/api/user', authRoute)
//start server
app.listen(5000);
# auth.js #
all routings are done in auth.js
const express =require('express')
const router = express.Router();
const User = require('./moduls/User')
router.get('/',(req, res)=>{
res.send('home')
})
//validation schema
const joi =require('#hapi/joi');
const regSchema ={
name:joi.string().min(6).required(),
email:joi.string().required().email(),
password:joi.string().min(8).required()
}
router.post('/register', async(req, res)=>{
//check and return error status
const { error } = joi.ValidationError(regSchema);
if(error) return res.status(400).json({message: err})
const emailExist = await User.findOne(req.body.email)
if (emailExist) return res.status(400).json({message:'there is a user with this email'})
//get user object
const user =new User({
name:req.body.name,
email:req.body.email,
password:req.body.password,
rePassword:req.body.rePassword
})
try{
await user.save()
.then(data=>{
res.json(data)
})
}
catch(err){
res.status(400).json({message: err})
}
})
module.exports=router;
modules/User.js
user module in the modules folder
const mongoose = require('mongoose')
const userSchema =new mongoose.Schema({
name:{
type: String,
required:true,
min:6,
max:30
},
email:{
type: String,
required:true,
max:100
},
password:{
type:String,
required:true,
min:8
},
rePassword:{
type:String,
required:true,
min:8
},
date:{
type:Date,
default:Date.now()
}
})
module.exports = mongoose.model('User', userSchema)
The .save() function returns a promise that you can await. You don't need to use .then() when using async/await.
Instead of this.
await user.save()
.then(data=>{
res.json(data)
})
I'd do this.
const data = await user.save();
res.json(data);

"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