unique attribute is not working mongoose duplicates are still being added - node.js

so i tried prev solutions to this issue
1-dropping collection
2-dropping database
3-adding dropDups
nothing worked
const userSchema = new Schema({
name: {
type: String,
required: [true, "please Enter your Name"],
lowercase: true,
},
username: {
type: String,
required: [true, "please Enter your user name"],
index: { unique: true, dropDups: true },
},
email: {
type: String,
required: [true, "please Enter your Email"],
unique: true,
lowercase: true,
validate: [isEmail, "please Enter a valid Email"],
},
password: {
type: String,
required: [true, "please Enter a Password"],
minlength: [8, "minimum password length is 8 characters"],
},
address: {
type: String,
required: [true, "please Enter your address"],
},
});
module.exports = User = mongoose.model("user", userSchema);
if anyone has an updated solution that would be great

what are you using to add a new user?
I had the same issue i was using User.create(...)
Instead use new User (...) as so
async addUser(req, res) {
const { name, username, email, password, address } = req.body;
try {
const user = new User({
name: name,
username: username,
email: email,
password: password,
address: address,
});
const data = await user.save();
res.status(201).json(data);
} catch (err) {
res.status(400).send(err);
}

Related

role object default value is selected even after specifying a different value from the object enum in mongoose schema

I have created a schema named userschema.The role object default value is selcted even after specifying a different value from role enum. If I change role manually in the database everything
works fine.
Check the image below.
const mongoose = require('mongoose');
const validator = require('validator');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true , 'Name is Required'],
unique: true
},
email: {
type: String,
required: [true , "E-mail is Required"],
trim: true,
lowercase: true,
unique: true,
validator:[validator.isEmail , 'Enter a Valid Email']
},
photo: {
type: String,
},
role:{
type:String,
enum: ["user","guide","lead-guide","admin"],
default:"user"
},
password: {
type: String,
trim: true,
minlength:8,
required: [true , 'Enter a Password'],
select:false
},
passwordConfirm: {
type:String,
trim:true,
required: [true , 'Confirm Password'],
validate: {
validator:function(el){
return el === this.password;
},
message: 'Did not match the above password!'
}
},
passwordChangedAt: Date
});
List item
In the post request the role has value of "admin". But after sending the request the role value is "user" which is also the default value in the role object.

MongoDB - altering the unique property of my field in schema - is not reflecting during my new insertions

I have my MongoDb database named School.
I have "user" collection.
The below is my Schema
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const userSchema = mongoose.Schema(
{
first_name: {
type: String,
required: [true, "first name required"],
trim: true,
text: true,
},
last_name: {
type: String,
required: [true, "last name required"],
trim: true,
text: true,
},
username: {
type: String,
required: [true, "user name required"],
trim: true,
unique: true,
},
email: {
type: String,
required: [true, "email required"],
trim: true,
unique: true,
},
password: {
type: String,
required: [true, "first name required"],
trim: true,
text: true,
}
});
module.exports = mongoose.model('User',userSchema);
In the above schema, email, username are unique.
But even though I pass duplicate values, the insertions are successful.
MY controller.js
const User = require("../models/User");
const bcrypt = require("bcrypt");
const { validateEmail, validateLength } = require("../helpers/validation");
exports.register = async (req, res) => {
try {
const {
first_name,
last_name,
email,
username,
password,
bYear,
bDay,
bMonth,
gender,
} = req.body;
if (!validateEmail(email)) {
return res.status(500).json({
message: "Email is invalid",
});
}
if (!validateLength(first_name, 3, 30)) {
return res.status(500).json({
message:
"First Name - Format Mismatch- Min length - 3 , Max Length - 30",
});
}
const cryptedPassword = await bcrypt.hash(password, 12);
console.log("crypted =" + cryptedPassword);
const user = await new User({
first_name,
last_name,
email,
username,
password : cryptedPassword,
bYear,
bDay,
bMonth,
gender,
}).save();
res.status(200).json(user);
} catch (err) {
console.log(err);
}
};
I have deleted my 'User' collection and again tried to run the 'post' request from Postman. But still, duplicates are getting inserted.
Please suggest me a solution.
Try to set your index by declaring on the schema with the index function:
const mongoose = require('mongoose');
const { ObjectId } = mongoose.Schema;
const userSchema = mongoose.Schema({
first_name: {
type: String,
required: [true, 'first name required'],
trim: true,
text: true,
},
last_name: {
type: String,
required: [true, 'last name required'],
trim: true,
text: true,
},
username: {
type: String,
required: [true, 'user name required'],
trim: true,
unique: false,
},
email: {
type: String,
required: [true, 'email required'],
trim: true,
unique: false,
},
password: {
type: String,
required: [true, 'first name required'],
trim: true,
text: true,
},
});
// Define your index
userSchema.index({ username: 1, email: 1 }, { unique: true });
module.exports = mongoose.model('User', userSchema);

Why is the select:false property on mongoose schema not working?

I have the following schema for a mongoose model:
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'User must have a name'],
unique: true
},
photo: String,
password: {
type: String,
required: [true, 'User must have a passwod'],
select: false,
minlength: 8
},
passwordConfirm: {
type: String,
required: ['Please confirm the passwod'],
select: false,
validate: {
validator: function(val) {
return this.password === val;
},
message: 'Password and passwordConfirm do not match'
}
}
});
Since password is set as Select:false, it should not be present in the queried object. However, when i create a document as below, it always has the password present:
const user = await userModel.create({
name: req.body.name,
email: req.body.email,
password: req.body.password,
passwordConfirm: req.body.passwordConfirm
});

Sub-schema properties are not updated mongoose

little bit stuck with one issue which is related to mongoose. I have a Project schema with sub-schema(SingleUserSchema). Whenever I add a new User to this schema it saves everything and that's ok. The issue is that if I update the user, old values in schema does not update. Any ideas how to solve this case? Stuck here for a whole day already.
Schema:
const mongoose = require('mongoose');
const SingleUserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
},
role: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
});
const ProjectSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, 'Provide project name'],
minlength: 5,
},
description: {
type: String,
required: [true, 'Provide description about the project'],
},
maxWorkingEmployees: {
type: Number,
required: [
true,
'Provide maximum number of employees working on this project',
],
},
currentlyWorkingEmployees: [SingleUserSchema],
status: {
type: String,
enum: ['Pending', 'In progress', 'Paused', 'Delayed', 'Completed'],
default: 'Pending',
},
createdBy: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('Project', ProjectSchema);
Controller:
const attachEmployeeToProject = async (req, res) => {
const { projectId, userId } = req.params;
const project = await Project.findOne({ _id: projectId });
const user = await User.findOne({ _id: userId });
if (!user) {
throw new NotFoundError(`User with id ${userId} does not exists`);
}
if (!project) {
throw new NotFoundError(`Project with id ${userId} does not exists`);
}
const { role, email, status } = user;
const SingleUserSchema = {
email,
role,
status,
};
let currentlyWorkingEmployees = [
...project.currentlyWorkingEmployees,
SingleUserSchema,
];
req.body.currentlyWorkingEmployees = currentlyWorkingEmployees;
const updateProject = await Project.findOneAndUpdate(
{ _id: projectId },
req.body,
{
new: true,
runValidators: true,
}
);
res.status(StatusCodes.OK).json({ updateProject });
};
Maybe I just simply need to create a reference? Tried like this and received tons of errors, also felt lost how to create n references in array.
currentlyWorkingEmployees: [
{ type: mongoose.Schema.ObjectId, ref: 'User', required: true },
],
User schema:
const UserSchema = new mongoose.Schema({
username: {
type: String,
required: [true, 'Please provide username'],
minlength: 3,
maxlength: 50,
},
email: {
type: String,
required: [true, 'Please provide username'],
unique: true,
validate: {
validator: validator.isEmail,
message: 'Please provide valid email address',
},
},
password: {
type: String,
required: [true, 'Please provide password'],
validator: {
validate: {
validator: validator.isStrongPassword,
message: 'Please provide stronger password',
},
},
},
firstname: {
type: String,
required: [true, 'Please provide first name'],
},
lastname: {
type: String,
required: [true, 'Please provide last name'],
},
status: {
type: String,
enum: ['Working', 'Pause', 'Offline'],
default: 'Offline',
},
role: {
type: String,
enum: [
'Developer',
'Analyst',
'Designer',
'Architect',
'Project Manager',
'Owner',
'Teamleader',
'Employee',
],
default: 'Employee',
},
verificationToken: {
type: String,
},
isTokenVerified: {
type: Boolean,
default: false,
},
tokenValidationDate: {
type: Date,
default: null,
},
});
First, as far as I see you don't have a model called 'User' so that's the reason why your reference is not working.
currentlyWorkingEmployees: [
{ type: mongoose.Schema.ObjectId, ref: 'User', required: true },
]
https://mongoosejs.com/docs/populate.html
Second, you need to identify the user you want to update (based on userId) inside currentlyWorkingEmployees collection, if I understood correctly your problem.
Hope it helps!

Mongoose Unique Email Address Validation

I am trying to enforce a Unique Email address when a user signs up. But Mongoose does not seem to be obeying the unique: true flag in my schema.
// NPM Packages
import * as mongoose from 'mongoose';
import * as bcrypt from 'bcrypt';
export const UserSchema = new mongoose.Schema(
{
firstName: {
type: String,
trim: true,
required: [true, 'Please enter First Name'],
},
lastName: {
type: String,
trim: true,
required: [true, 'Please enter Last Name'],
},
email: {
type: String,
match: [
/^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
'Please add a valid email address.',
],
required: [true, 'Please enter Email Address'],
unique: true,
lowercase: true,
},
password: {
type: String,
required: [true, 'Please enter a password'],
minlength: [6, 'Password must be at least 6 characters'],
select: false,
},
},
{ timestamps: true },
);
// Encrypt User Password
UserSchema.pre('save', async function(next) {
const salt = await bcrypt.genSalt(10); // Recommended in bcryptjs doc
this.password = await bcrypt.hash(this.password, salt);
});
Use dropDups in your schemas like
email: {
type: String,
match: [
/^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
'Please add a valid email address.',
],
required: [true, 'Please enter Email Address'],
unique: true,
lowercase: true,
dropDups: true
}

Resources