Mongoose error with PUT request but not with POST or GET - mongodb

I have a schema that looks like:
const houseSchema = new mongoose.Schema({
address: {
type: String,
required: true,
trim: true,
},
city: {
type: String,
required: true,
},
roofType: {
type: String,
//required: true,
},
repairType: {
type: String,
//required: true,
},
numFloors: {
type: Number,
//required: true,
},
isOwner: {
type: Boolean,
//required: true,
},
isGated: {
type: Boolean
},
includeFlat: {
type: Boolean
},
addedBy: [
{
name:{
type: String
},
time:{
type: String
},
}
],
});
const customerSchema = new mongoose.Schema({
firstName: {
type: String,
required: true,
trim: true,
},
lastName: {
type: String,
required: true,
trim: true,
},
phoneNumber: {
type: String,
required: true,
},
email: {
type: String,
},
//array of houseSchema objects
properties: [
houseSchema
],
});
And my endpoint that is used to update one of the 'properties' is:
router.route('/property').post(async (req,res) => {
const body = req.body;
Customer.updateOne({_id: req.query.id, properties: {$elemMatch: {_id: req.query.pId}}},
{
$set: {
"properties.$.address": body.address,
"properties.$.city": body.city,
"properties.$.roofType": body.roofType,
"properties.$.repairType": body.repairType,
"properties.$.numFloors": body.numFloors,
"properties.$.isOwner": body.isOwner,
"properties.$.isGated": body.isGated,
"properties.$.includeFlat": body.includeFlat
}
},
function(err){
if(err){
res.status(400).json('Error: ' + err);
}
else{
res.json('Property Updated!');
}
}
)
});
The endpoint works mostly fine (it returns the customer and all properties when i only search for and want to modify one of the 'properties') but only when it is a post or a get request and when it is a put request, the error says
Error: ValidationError: firstName: Path firstName is required., lastName: Path lastName is required., phoneNumber: Path phoneNumber is required.
I dont know if its a big deal or not, but I do not know why this is happening and would like to know. Just to be clear, the goal of this endpoint is to find one of the properties and update its values, not to change anything about a customer or any of their other properties.

Related

mongoose validator not working as expected

i want to add batch,department,stream,id fields to the schema depending if usertype is “Student”,i do not understand why,but sometimes it adds the fields sometimes not.forexample if i created a user with usertype “Student” first it does not add the fields,but after that when i created a user with usertype “Teacher” or “Admin” it asks me the fields are required meaning it add the fields and this happens vice versa.why any way to fix this issue?please help guys.
what i have tried well,i have asked chatGpt but no answers i mean just the answers do not solve the issue.
here is the code
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
fullName: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
userType: {
type: String,
required: true,
},
phoneNumber: { type: String, required: true },
password: { type: String, required: true },
approved: { type: Boolean, default: true },
},
{
timestamps: true,
}
);
userSchema.pre("validate", function (next) {
if (this.userType === "Student") {
this.constructor.schema.add({
batch: {
type: Number,
required: true,
},
department: {
type: String,
required: true,
},
stream: {
type: String,
required: true,
},
id: { type: String, required: true }, //, unique: true
});
}
next();
});
const userModel = mongoose.model("users", userSchema);
module.exports = userModel;

Re: Correct MongoDb Relationships

Hi clever MongoDB people,
I am extremely new to Mongo DB and am trying to teach myself coding but I am battling with the practical side of collections.
I am attempting to create an employee management system and would like to know how do I get the different schemas/collections to only deal with the individual User’s employees.
A user will register using this schema;
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
lowercase: true,
},
companyName: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
role: {
type: String,
default: "customer",
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const User = mongoose.model("User", UserSchema:
);
module.exports = User;
Then the system takes them to a Profile page where they create a profile;
Profile Schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ProfileSchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
},
contactPerson: {
type: String,
required: true,
},
companyName: {
type: String,
required: true,
},
mobileNo: {
type: String,
required: true,
},
workNo: {
type: String,
},
email: {
type: String,
required: true,
},
industry: {
type: String,
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const Profile = mongoose.model("Profile", ProfileSchema);
module.exports = Profile;
Then they can add their employees.
Employee Schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const EmployeeSchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
},
employeeNo: {
type: String,
},
title: {
type: String,
},
employeeName: {
type: String,
required: true,
},
surname: {
type: String,
required: true,
},
gender: {
type: String,
},
race: {
type: String,
},
passportNo: {
type: String,
},
IDnumber: {
type: Number,
},
DOB: {
type: Date,
},
aka: {
type: String,
},
midName: {
type: String,
},
marriage: {
type: String,
},
passportExpires: {
type: Date,
},
mobileNo: {
type: String,
},
empEmail: {
type: String,
lowercase: true,
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const Employee = mongoose.model("Employee", EmployeeSchema);
module.exports = Employee;
Once an employee has been created there are various schemas connected with the employee, such as Personal contact details schema, Job details schema, Emergency contact details schema and so on.
This is my Emergency contact details schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const EmergencySchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
},
emergContactPerson: {
type: String,
required: true,
},
emergWorkNo: {
type: String,
},
emergMobileNo1: {
type: String,
required: true,
},
emergMobileNo2: {
type: String,
},
medicAidName: {
type: String,
},
medicPlan: {
type: String,
},
medicMemberNo: {
type: String,
},
medicDepCode: {
type: Number,
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const Emergency = mongoose.model("Emergency", EmergencySchema);
module.exports = Emergency;
My question is How do I create a one-to-many relationship between my schemas so that each User will only see their employees and their personal details?
Please can you help me?

How to develop nested condition query in mongoDB

I am pretty new to mongoDb and want to apply nested query.
I have a business schema like this:
const businessSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
businessType: {
type: Schema.Types.ObjectId,
ref: "businessCategory",
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
select: false,
},
review: {
type: [reviewSchema],
},
isDeleted: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
Business has a review where user can do the review and reviewSchema is
const reviewSchema = new mongoose.Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: "users",
required: true,
},
rating: {
type: Number,
enum: [1, 2, 3, 4, 5],
},
reviewArray: {
type: [singleReviewSchema],
},
},
{ timestamps: true }
);
One user can do many reviews, and it has reviewArray.
ReviewArray schema is
const singleReviewSchema = new mongoose.Schema(
{
title: {
type: String,
},
description: {
type: String,
},
isDeleted: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
How to fetch the business with a condition business: isDeleted:false and its reviews with singleReviewSchema: isDeleted:false
I dont know your model names, so please replace path with correct names
but it might look like:
businnesModel.find({isDeleted: false})
.populate({
path: 'reviewModelName',
model: 'review',
populate: {
path: 'reviewArray',
model: 'singleReviewModelName',
match: {
isDeleted : false
}
}
})
It should provide you array of businessModel documents - even when their singleReviews array will be empty (because all of reviews are deleted, or there was zero reviews). So you have to filter it out in JS.
To avoid filtering in JS, and to do it a bit more efficient way for mongodb, you can go with aggregate instead.

find one with multiple conditions mongoose mongodb

I am trying to obtain data from mongodb. This is the scenario. Each user has a following property(array) that takes an array of users id.
The user model is as below
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
followers: [{ type: mongoose.Types.ObjectId, ref: "user" }],
following: [{ type: mongoose.Types.ObjectId, ref: "user" }],
});
in simple terms. I need to use two conditions where postedBy: { $in: req.user.following }, or postedBy:req.user._id
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
body: {
type: String,
required: true,
},
photo: {
type: String,
required: true,
},
likes: [{ type: mongoose.Schema.ObjectId, ref: "user" }],
comments: [
{
text: String,
postedBy: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
},
],
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
},
});
I have not figured out the second condition to add in the code below.
router.get("/getSubPost", requireLogin, async (req, res) => {
try {
const result = await Post.find({
postedBy: { $in: req.user.following },
})
.populate("postedBy", "-password")
.populate("comments.postedBy", "_id name");
res.json({ result });
} catch (error) {
console.log(error);
}
});

MongoDB (mongoose) about refs

who can explain with example how to get from another schema user data (for example useravatar)
while i read about refs and i cant understand.
This is my code, but i want to send back not only article but with profile datas about author. How can i do this ? I have authorID already for this.
router.post('/get-article', (req, res) => {
const { id, authorID } = req.body.data;
Article.findByIdAndUpdate({ _id: id }, { $inc: { "pageview": 1 } }, (err, article) => {
if (err) return res.status(400).json({ NotFound: "Article Not Found" })
res.json({ article })
})
})
article schema
const schema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: { type: String, required: true },
image: { type: String, required: true },
content: { type: String, required: true },
email: { type: String, required: true },
author: { type: String, required: true, index: true },
added: { type: Date, default: Date.now },
pageview: { type: Number, default: 0 }
});
User schema
const schema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
username: { type: String, required: true },
email: { type: String, required: true },
facebookId: { type: String },
githubId: { type: String },
googleId: { type: String },
useravatar: { type: String, required: true },
userip: { type: String, required: true },
accessToken: { type: String },
date: { type: Date, default: Date.now }
});