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)
Related
I'm having trouble with my server routes. is there any problem with my routes? or a problem with the code?
I have checked all the possible question answers.
I'm having trouble with my server routes.
used thunderclient to send request
when I route it shows this
enter image description here
I tried to set thunder client POST to GET but got the same error
Index.js
const connectToMongo = require('./db');
const express = require('express')
connectToMongo();
const app = express()
const port = 5000
//Available Routes
app.use('/api/auth', require('./routes/auth'))
// app.use('./api/notes', require('./routes/notes'))
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
my auth.js where login and register exist.
const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { body, validationResult } = require('express-validator');
// Create a User using: POST "/api/auth/". Doesn't require auth
router.post('/',[
body('name').isLength ({min: 3}),
body('email').isEmail(),
body('password').isLength ({min: 5})
], (req, res)=>{
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
res.send(req.body);
})
module.exports = router
my user.js which shows user data
const mongoose = require('mongoose');
const {Schema}= mongoose;
const UserSchema = new Schema({
name:{
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password:{
type: String,
required: true
},
date:{
type: Date,
default: Date.now
},
});
module.exports = mongoose.model('user', UserSchema);
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"))
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.
I am trying to send data from data.js file to mongoDB:
const data = {
users: [
{
name: 'MrAdmin',
email: 'admin#example.com',
password: bcrypt.hashSync('1234', 8),
isAdmin: true,
},
{
name: 'Tom',
email: 'tom#gmail.com',
password: bcrypt.hashSync('1234', 8),
idAdmin: false,
},
{
name: 'John ',
email: 'John77#gmail.com',
password: bcrypt.hashSync('1234', 8),
idAdmin: false,
},
],
}
user model:
const userSchema = new mongoose.Schema({
name: {type: String, required: true},
email: {type: String, required: true, unique: true},
password: {type: String, required: true},
isAdmin: {type: Boolean, default: false, required: true}
},{
timestamps: true,
});
server / api :
import express from 'express';
import mongoose from 'mongoose';
import productRouter from './routers/productRouter.js';
import userRouter from './routers/userRouter.js';
const app = express();
const uri = process.env.MONGODB_URL;
mongoose.connect(uri || 'mongodb://localhost:27017/e-commerce-shop', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
}).then(() => console.log( 'Database Connected' ))
.catch(err => console.log( err ));;
app.use('/api/users', userRouter);
app.use('/api/products', productRouter);
app.get('/', (req, res)=>{
res.send('Working...');
});
app.use((err, req, res, next)=>{
res.status(500).send({message: err.message});
});
const port = process.env.PORT || 5000;
app.listen(port, ()=>{
console.log(`Server at http://localhost:${port}`);
});
user router:
import express from 'express';
import data from '../data.js';
import expressAsyncHandler from 'express-async-handler';
import User from '../models/userModel.js';
const userRouter = express.Router();
userRouter.get('/seed', expressAsyncHandler(async(req, res)=>{
//await User.remove({});
const createdUsers = await User.insertMany(data.users);
res.send({createdUsers});
}));
export default userRouter;
Data.js file has 3 elements inside users array. I can use just first and second user on my website. Moreover, mongoDb compass doesn't seem to get the third user (John). I have products section too. Metodolgy is completely the same as here and I can't get more than 2 elements as well(first and second product is visible for mongoDB compass and it is possible to render them, unlike the rest)
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