unable to insert user data into database - javascript

i am try to inser user data into my database but data is not inserting and it is showing like User already exist with this email
How can solve this one ?
My code is below
i had tried with different email even though it is User already exist with this email and it is not inserting in the database.
server.js
require("dotenv").config();
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const port = process.env.PORT || 3500;
app.use(express.json());
//DB connection
mongoose
.connect(process.env.MONGO_URL)
.then(() => console.log("DB Connection Successful"))
.catch((err) => console.log(err));
//Routes
app.use("/api/auth/", require("./routes/auth"));
app.listen(port, () => {
console.log("Server is running on Port " + port);
});
user.js
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const userSchema = new mongoose.Schema(
{
firstName: { type: String, required: true, trim: true, min: 3, max: 30 },
lastName: { type: String, required: true, trim: true, min: 3, max: 30 },
userName: {
type: String,
required: true,
trim: true,
min: 3,
max: 30,
unique: true,
index: true,
lowercase: true,
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true,
},
userPassword: { type: String, required: true },
role: { type: String, enum: ["user", "admin"], default: "admin" },
contactNumber: { type: String },
profilePicture: { type: String },
},
{ timestamps: true }
);
userSchema.virtual("password").set(function (password) {
this.userPassword = bcrypt.hashSync(password, 10);
});
userSchema.methods = {
authenticate: function (password) {
return bcrypt.compareSync(password, this.userPassword);
},
};
module.exports = mongoose.model("User", userSchema);
auth.js
const router = require("express").Router();
const User = require("../models/user");
router.post("/signin", (req, res) => {});
router.post("/register", async (req, res) => {
const user = User.findOne({ email: req.body.email });
if (!user) {
const newUser = new User(req.body);
await newUser.save();
res.status(201).json({
user: newUser,
});
} else {
res.status(400).json({
message: "User already exist with this email",
});
}
});
module.exports = router;
please find the attached images

Querying the database is an asynchronous function call.
Here at the auth.js, You're checking asynchronous if the user exits. const user = User.findOne({ email: req.body.email });
You should add await like that: const user = await User.findOne({ email: req.body.email });
Since, its asyncourouns Javascript doesn't wait for the answer and assings undefined to the user variable.
Therefore you end up at your else statement.

Related

User.create is not a function in mongoDB

I'm learning the MERN stack and trying to create an authentication, but now I have a problem, whenever I'm trying to register, I have an error 'TypeError: User.create is not a function'.
I think that I have a problem with user model or export. Please help
INDEX.JS
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const dotenv = require("dotenv");
const app = express();
const User = require("./models/User");
dotenv.config({ path: "./.env" });
app.use(express.json());
app.use(cors());
mongoose.connect(process.env.MBD_CONNECT, { useNewUrlParser: true }, (err) => {
if (err) return console.error(err);
console.log("Connected to MongoDB");
});
app.post("/api/registr", async (req, res) => {
console.log(req.body);
try {
const user = await User.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password,
});
res.json({ status: "ok" });
} catch (err) {
console.log(err);
res.json({ status: "error", error: "Duplicate email" });
}
});
app.post("/api/login", async (req, res) => {
const user = await User.findOne({
email: req.body.email,
password: req.body.password,
});
if (user) {
return res.json({ status: "ok", user: true });
} else {
return res.json({ status: "error", user: false });
}
});
app.listen(3001, () => {
console.log("SERVER RUNS PERFECTLY!");
});
USER.JS (MODEL)
const mongoose = require("mongoose");
const User = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
const model = mongoose.model("UserData", User);
module.exports = User;
You're exporting the schema, not the model. create is a method of mongoose Model class, see document here.
const model = mongoose.model("UserData", User);
module.exports = User; // <------ problem here
It should be:
const model = mongoose.model("UserData", User);
module.exports = model;
Your model file please update with the following code snip
const mongoose = require("mongoose");
const User = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
}, { collection : 'UserData'});
const model = mongoose.model("UserData", User);
module.exports = User;

Missing required parameter - public_id (Cloudinary)

I am going through the full stack developer certification and creating an authentication app from devChallenges.io and I want the user to able to edit their profile and pass in the new profile image as well as their name, bio, phone number and password in the form data however, I get the error Missing required parameter - public_id. Here is my code below.
// #route POST /profile/edit/:id
// #desc edit profile
// #access Private
app.put('/profile/edit/:id', upload.single('image'), auth, async (req, res) => {
const { name, bio, phone, password } = req.body;
try {
let user = await AuthUser.findById(req.params.id);
// Delete image from cloudinary
await cloudinary.uploader.destroy(user.cloudinary_id);
// Upload image to cloudinary
let result;
if (req.file) {
result = await cloudinary.uploader.upload(req.file.path);
}
const data = {
name: name || user.name,
avatar: result.secure_url || user.avatar,
bio: bio || user.bio,
phone: phone || user.phone,
password: password || user.password,
cloudinary_id: result.public_id || user.cloudinary_id,
};
// Encrypt password
const salt = await bcrypt.genSalt(10);
data.password = await bcrypt.hash(password, salt);
// Update
user = await User.findByIdAndUpdate(req.params.id, data, { new: true });
return res.json(user);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
models/user.js
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
default: '',
},
email: {
type: String,
unique: true,
required: true,
},
password: {
type: String,
required: true,
},
avatar: {
type: String,
},
bio: {
type: String,
default: '',
},
phone: {
type: String,
default: '',
},
cloudinary_id: {
type: String,
},
});
module.exports = AuthUser = mongoose.model('AuthUser', UserSchema);

Pushing subdocument to parent document array. Only Object_ID gets pushed

I'm quite new to mongoose. I have found similar questions on here that do answer them, but they are not quite like my problem / I can't find out how it's similar.
I'm trying to push a subdocument into an array on my parent document. Currently I do that like this:
Upload-soundboard
const multer = require('multer')
const FILE_PATH = 'uploads'
const passport = require('passport')
const strategy = require('../strategies/strategy')
const upload = multer({
dest: `${FILE_PATH}/`
})
const { Soundboard } = require('../models/soundboard')
const express = require('express')
const router = express.Router()
passport.use(strategy.jwtStrategy)
router.post('/', passport.authenticate('jwt', { session: false }), async (req, res) => {
try {
//console.log(req.body.name)
req.user.soundboards.push({
name: req.body.name,
})
//console.log(req.user.soundboards)
await req.user.save()
res.send('Success!')
} catch (err) {
res.status(500).send(err)
}
})
module.exports = router
This does in fact push a subdocument to the array, but it only adds the Object.ID, and not the name I requested. The schema's look like this:
USER
const User = mongoose.model('User', new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
email: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
password: {
type: String,
required: true,
minlength: 5,
maxlength: 1024
},
soundboards: [SoundboardSchema]
}))
SOUNDBOARD
const Soundboard = new Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
sounds: {
type: [SoundSchema],
required: false
}
})
SOUND
const Sound = new Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
path: {
type: String,
required: true
}
})
Does anyone see the answer? Thanks in advance!
This is how you should use it instead:
router.post('/', passport.authenticate('jwt', { session: false }), async (req, res) => {
try {
let newSoundboards = {
name: req.body.name,
}
//I don't see you loading your model somewhere with the connection
//So I used yourDB as an example.
await new yourDB(newSoundboards).save()
res.send('Success!')
} catch (err) {
res.status(500).send(err)
}
})

Why do I keep getting TypeError: User is not a constructor?

I'm practicing creating models and routes and am using postman to send a POST request to test it out. However, I keep getting the user is not a constructor error.
index.js (route)
const express = require('express')
require('./db/mongoose')
const User = ('./models/user')
const app = express()
const port = process.env.PORT || 3000
app.use(express.json())
app.post('/users', (req, res) => {
const user = new User(req.body)
user.save().then(() => {
res.send(user)
}).catch(() => {
})
})
app.listen(port, () => {
console.log(port + ' is aliiiiiiiive!')
})
User (schema)
const mongoose = require('mongoose')
const validator = require('validator')
const User = mongoose.model('User', {
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
require: true,
trim: true,
lowercase: true,
validate(value) {
if(!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
age: {
type: Number,
default: 0,
validate(value) {
if(value < 0) {
throw new Error('Age must be a positive number.')
}
}
},
password: {
type: String,
trim: true,
lowercase: true,
required: true,
minlength: 7,
validate(value) {
if( value.toLowerCase().includes("password")) {
throw new Error("Password can't be 'password'.")
}
}
}
})
module.exports = User
mongoose.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/task-manager-api', {
useNewUrlParser: true,
useCreateIndex: true
})
I expect it to send back an object with the following information I'm sending on Postman:
{
"name": "Michael",
"email": "email#eail.com",
"password": "ThisIsAPassword"
}
You have to define a userSchema before compiling the model, like this:
const mongoose = require('mongoose')
const validator = require('validator')
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
require: true,
trim: true,
lowercase: true,
validate(value) {
if(!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
age: {
type: Number,
default: 0,
validate(value) {
if(value < 0) {
throw new Error('Age must be a positive number.')
}
}
},
password: {
type: String,
trim: true,
lowercase: true,
required: true,
minlength: 7,
validate(value) {
if( value.toLowerCase().includes("password")) {
throw new Error("Password can't be 'password'.")
}
}
}
})
const User = mongoose.model('User', userSchema);
exports.User = User
Now it is a constructor, because we are saying each instance of User is a new instance of userSchema.
I figured it out. On the third in my index.js file, I left out require.
Instead of this:
const User = ('./models/user')
It should have been this:
const User = require('./models/user')
Thanks for all your help, everyone!

Why does Mongoose can't find an user on a query if it exists?

I've been working on a Nodejs+Express+Mongoose API that handles user registration/login, everything works perfectly when a user signs up, but when the user wants to login it says it can't find the user. Let me show you the code:
module.exports.registerUser = (req, res) => {
var user = new User();
user.email = req.body.email;
user.name = req.body.name;
user.setPassword(req.body.password);
user.save((err) => {
var token;
token = user.generateJwt();
res.status(200);
res.json({
'token': token,
'user': user,
});
});
};
When I register (I'm testing this with Postman) I get this message, showing everything it's OK:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODg1MDcwNjUsImlhdCI6MTQ4ODQyMDY2NX0.GD0NehQ1EYEnOKx2OJWALpkHB8u5N_9Zjm1dcuEdl7I",
"user": {
"__v": 0,
"name": "Stack Overflow",
"email": "stackoverflow#stackoverflow.com",
"_id": "58b77f39cf5e8d5f3ffdb4ff"
}
}
The password gets hashed, that's why the JSON doesn't contain it.
And this is the code for user login:
module.exports.loginUser = (req, res) => {
var password = req.body.password;
var email = req.body.email;
User.findOne({'email': email}, (err, user) => {
if (err) {
res.status(500).json(err);
}
if (user) {
if (!user.validPassword(password)) {
res.status(401).send({
message: 'Wrong password.'
});
} else {
token = user.generateJwt();
res.status(200);
res.json({
'token': token,
'user': user
});
}
} else {
res.status(404).send({
message: 'No user was found.'
});
}
});
}
But every time I hit the login button on postman with the same password and email, I get this:
{
"message": "No user was found."
}
And this is the user schema:
'use strict'
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var crypto = require('crypto');
var jwt = require('jsonwebtoken');
var secret = require('../config/secret');
var userSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
name: {
type: String,
required: true
},
age: {
type: Number,
required: false
},
schoolID: {
type: String,
required: false,
unique: false
},
university: {
type: String,
required: false
},
area: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Area'
},
project: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Project'
},
hash: String,
salt: String
});
userSchema.methods.setPassword = (password) => {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
};
userSchema.methods.validPassword = (password) => {
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
return this.hash === hash;
};
userSchema.methods.generateJwt = () => {
var expiry = new Date();
expiry.setDate(expiry.getDate() + 1);
return jwt.sign({
_id: this._id,
email: this.email,
name: this.name,
exp: parseInt(expiry.getTime() / 1000),
}, secret.secret);
};
var User = mongoose.model('User', userSchema);
module.exports = User;
I can't find the solution to this problem, because the way I see it, everything should be working just nice. Any ideas on why this isn't working?
Update:
This is for checking the email is being sent correctly:
{
"message": "No user was found. User: stackoverflow#stackoverflow.com password: stackoverflow"
}

Categories

Resources