MongoError: After applying the update to the document - node.js

I need some help.
I'm trying to make post req to this route:
router.post('/admin/editFront', isLoggedIn, (req, res, next) => {
req.checkBody('title', 'Title is require').notEmpty();
req.checkBody('aboutUs', 'About us section is require').notEmpty();
req.checkBody('email', 'Check email again').notEmpty().isEmail();
let errors = req.validationErrors();
if(errors) {
req.flash('error_msg', errors.msg);
console.log(errors);
}
let cube = ({
title: req.body.cubeTitle,
img: req.body.cubeImg,
info: req.body.cubeInfo
})
let front = new FrontInfo();
front.title = req.body.title;
front.aboutUs = req.body.aboutUs;
front.email = req.body.email;
front.phone = req.body.phone;
front.cube.push(cube);
// front.socialNet.push(req.body.social);
console.log(front);
FrontInfo.findOneAndUpdate({email: req.body.email}, front, { upsert: true }, (err, doc) => {
if(err) console.log(err);
else {
req.flash('success', doc);
res.redirect('/editFront');
}
});
});
Here is my Schema:
let cube = new Schema({
title: { type: String },
img: { type: String },
info: { type: String }
});
let socialNet = new Schema({
title: { type: String, required: true },
link: { type: String, required: true },
icon: { type: String, required: true }
});
let FrontInfo = new Schema({
title: { type: String, required: true },
aboutUs: {type: String, required: true},
phone: {type: String, minlength: 9, required: true},
email: {type: String, required: true},
cube: {type: [cube], default: []},
updateDate: {type: Date, default: Date.now}
});
So, if I try to create a new Schema it works.
But if I try to update the new one I get this error:
I spent a long time trying to fix it!
Please help me friends

When you use let front = new FrontInfo(); you are creating a new document that has its own _id. This _id is different from the _id of the document that you're updating. You are not allowed to update the _id field, which is why you get the error message
the (immutable) field '_id' was found to have been altered to _id
So instead of creating a new Mongoose document you should just create a new ordinary Javascript object instead:
let front = {};
front.title = req.body.title;
front.aboutUs = req.body.aboutUs;
front.email = req.body.email;
front.phone = req.body.phone;
front.cube = [];
front.cube.push(cube);
This only contains the fields that you've listed.

Related

How to update a specific nested array inside a MongoDB document

So I have a primary mongoDB object that has multiple documents nested within. I want to access a specific document in an array and modify one of its values. This is my document setup
const sectionSchema = new mongoose.Schema({
name: String,
items: [itemSchema],
currentAmount: {
type: mongoose.Decimal128,
default: 0
},
limitAmount: {
type: mongoose.Decimal128,
required: true
},
isActive: {
type: Boolean,
default: 0
}
});
const Section = new mongoose.model("Section", sectionSchema);
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique:true
},
email: {
type: String,
lowercase: true,
trim:true,
required: true,
unique: true
},
password: {
type: String,
required: true
},
sections: [sectionSchema]
});
const User = new mongoose.model("User", userSchema);
I've added some dummy values to fill the database, including the other testSection and testItems.
const testSection2 = new Section({
name: "Vacation",
items: [testItem3,testItem4],
currentAmount: 0,
limitAmount: 800,
isActive: 1
});
const testUser = new User({
username: "wavey123",
email: "wvy#123.com",
password: "wvy123",
sections: [testSection1,testSection2]
});
I've tried different iterations of the .findOneAndUpdate methods with no success like:
app.post("/sSelect", function(req,res){
const selectedSection = req.body.sectionName;
User.findOneAndUpdate({sections: {$elemMatch: {isActive: 1}}},{sections: {isActive: 0}},{new: true}, function(err, aSection){
if (err){
console.log(err)
}
console.log(aSection);
})
User.findOneAndUpdate(({sections: {$elemMatch: {name: selectedSection}}}),{$set: {sections: {isActive: 1}}},{new: true}, function(err, aSection){
if (aSection){
res.redirect("/");
}
})
I end up with my base document looking like this:
[
{
_id: ObjectId("629a971bb8a72843a07df0fd"),
username: 'wavey123',
email: 'wvy#123.com',
password: 'wvy123',
sections: [
{
currentAmount: Decimal128("0"),
isActive: false,
_id: ObjectId("629a9756792a3b21872c329f"),
items: []
}
],
__v: 0
}
]
This happens after the first .findOneAndUpdate. Cant seem to get my head around it.
so i just scrapped the whole .findOneAndUpdate and just used JS to find the isActive key and manipulate it like so:
app.post("/sSelect", function(req,res){
const selectedSection = req.body.sectionName;
User.findOne({}, function(err, aSection){
aSection.sections.forEach(function(section){
if(section.isActive === true){
section.isActive = false;
console.log(section.isActive)
aSection.save();
}
})
});
User.findOne({}, function(err, aSection){
aSection.sections.forEach(function(section){
if(section.name === selectedSection){
section.isActive = true;
console.log(section.name,section.isActive)
aSection.save();
}
})
});
res.redirect("/");
:)

How to save req.body object with a user ID

I am trying to save the request.body object containing an authenticated user ID into a new collection called useritems.
below is the req.body object with the user ID
{contact: "90000023", item: "Bread", price: "50", id: "5f4acf21287c6226ec0855af"}
next i find user with the id "5f4acf21287c6226ec0855af"
User.findOne({_id: _id}, function(err, items){
console.log(req.body)
if (err) {
console.log('err', err);
res.status(500).send(err);
} else {
const newItem = new Item ({
name:items.name,
email:items.email,
contact:req.body.contact,
item:req.body.item,
price:req.body.price,
});
newItem.save(function (err, item) {
if (err) {
console.log(err);
} else {
res.send(item);
}
});
)
}
})
})
here is the output:
{
_id: 5f4e32006ce4d91a1cd811e2,// mongodb assigns new id. However, i still want the userID (5f4acf21287c6226ec0855af) persisted
name: 'Bernad James',
email: 'Ben#gmail.com',
contact: 90000023,
item: 'Bread',
price: 50
}
how do I make it such that I am able to maintain the userID after save in the item collection
//here is my Item schema
const ItemSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
contact: {
type: Number,
required: true
},
item: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
And my user schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
I want the userID persisted throughout so that i can always reference it to deal with particular authenticated logged in user

MongoDB/Mongoose Populate

Working with Mongoose "Populate" - So far I'm unable to successfully get the "Food" model to populate the "User" model.
The goal is to be able to save a "Food" to a user.
USER MODEL:
var UserSchema = new mongoose.Schema({
username: String,
password: String,
foods: [{ type: mongoose.Schema.Types.ObjectId}],
easy: {type: Boolean, default: false},
});
UserSchema.plugin(passportLocalMongoose)
module.exports = mongoose.model("User", UserSchema);
FOOD MODEL:
var foodSchema = new mongoose.Schema({
name: { type: String, required: false, unique: true },
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
}
});
module.exports = mongoose.model("Food", foodSchema);
GET ROUTE
router.get("/dashboard", function (req, res) {
User.find({currentUser: req.user})
.populate({path: 'foods'}).
exec(function (err, foods) {
if (err) return (err);
console.log('The food is:', req.user.foods.name);
});
});
POST ROUTE:
router.post("/dashboard", function(req, res, next) {
User.update({ id: req.session.passport.user }, {
}, function(err, user) {
if (err) return next(err);
User.findById(req.user._id, function(err, user) {
var newFood = new Food({
name: req.body.currentBreakfast,
image: 'test',
});
user.foods = newFood
user.save();
});
});
res.redirect('/dashboard');
});
You need to add the ref field in your user schema for foods to be populated while querying user.
var UserSchema = new mongoose.Schema({
username: String,
password: String,
foods: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Food' }],
easy: {type: Boolean, default: false},
});
You can user this query.
await User.find({currentUser: req.user}).populate('foods')
Try this it will auto-populate data
var UserSchema = new mongoose.Schema({
username: String,
password: String,
foods: [{ type: mongoose.Schema.Types.ObjectId,ref: 'Food'}}],
easy: {type: Boolean, default: false},
});
UserSchema.pre('find', prepopulate)
function prepopulate(){
return this.populate('foods')
}

two errors displayed if i sort one the other pops up TypeError: cart is not a constructor in post method and cart.find is not a function

TypeError: cart is not a constructor have been working with these tech for over year and never faced such issues so please do help
router.post('/add-to-cart', isLoggedIn, function (req, res, next) {
cart = new cart({
price: req.body.price,
adult: req.body.adult,
children: req.body.children,
kids: req.body.kids,
arrival: req.body.arrival,
departure: req.body.depart,
totalprice: req.body.subtotal,
user_id: req.body.userid,
id: req.body.productId,
});
console.log("cart1592: " + cart);
cart.save(function (err) {
if (err) {
console.log('error', 'Error: ' + err.message);
console.log("cart1596: " + cart);
return res.redirect('/');
}
// res.flash('thanks for your feedback');
console.log("cart1600: " + cart);
return res.redirect('/shopping-cart');
});
});
imported it here
var router = express.Router();
var cart = require('../models/cart');
var review = require('../models/reviews');
cart.find is not a function have been working with these tech for over year and never faced such issues so please do help
router.get('/shopping-cart', isLoggedIn, function (req, res, next) {
var slug3 = req.params.slug3;
qryFilter = { "_id": req.user._id };
var user = req.user._id;
console.log(user);
cart.find(function (err, cart) {
console.log(cart);
event = new Event({
namespace: 'products',
person: {
id: req.user._id,
first_name: req.user.first_name,
last_name: req.user.last_name,
email: req.user.email,
},
action: 'view',
thing: {
type: "product",
id: product._id,
name: product.name,
category: product.category,
Product_Group: product.Product_Group
}
});
event.save(function (err, eventId) {
if (err) {
return -1;
}
res.send(cart);
});
});
});
this is my schema have been working with these tech for over year and never faced such issues so please do help
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schema = new Schema({
price: {
type: Number,
required: false
},
adult: {
type: Number,
required: false
},
children: {
type: Number,
required: false
},
id: {
type: String,
required: false
},
kids: {
type: Number,
required: false
},
arrival: {
type: Date,
required: false
},
user_id: {
type: String,
required: false
},
departure: {
type: Date,
required: false
},
totalprice: {
type: Number,
required: false
},
});
module.exports = mongoose.model('cart',schema);
error solved The reason is because on declaring var cart that overwrites the other declaration i had for cart so it displayed cart is not constructor.so it was either this or that one of them only worked and one condition failed each time thanks for the response

Having an issue getting user id

So I am working on building a web app and I have a lot of it working. However I am trying to link my user._id to my items database. But when I try to post an item using postman the app crashes saying it cant read property '_id' of null. I know I am missing something but I honestly can't figure out what other code I need to implement. Any help would be great. Thanks
Here is the code for the UserSchema:
const mongoose = require('mongoose');
const passportLocalMongoose = require("passport-local-mongoose");
const UserSchema = new mongoose.Schema({
username: {
type: String,
trim: true,
unique: true,
required: true,
minlength: 3,
maxlength: 15
},
firstName: {
type: String,
required: true,
minlength: 3,
maxlength: 15
},
lastName: {
type: String,
required: true,
minlength: 3,
maxlength: 15
},
email: {
type: String,
unique: true,
required: true
},
resetPasswordToken: String,
resetPasswordExpires: Date,
isAdmin: {
type: Boolean,
default: false
}
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("user", UserSchema);
Here is the code for the ItemSchema:
const mongoose = require('mongoose');
const User = require('./user');
const ItemSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 3,
maxlength: 20
},
description: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
createdBy: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model("items", ItemSchema);
And here is the code for the route thats throwing the error:
const express = require("express");
const router = express.Router();
const User = require("../models/user");
router.route("/item/add")
.post(function(req, res) {
User.findById(req.user._id, function(user, err) {
if (err) {
console.log(err);
}
var item = new Item();
item.name = req.body.name;
item.description = req.body.description;
item.price = req.body.price;
item.createdBy = { id: req.user._id, username: req.user.username };
item.save(function(err) {
if (err) {
res.send(err);
}
res.json({ message: "Item was successfully saved" });
console.log(item);
});
});
});
You need to send your data in json format in postman for example:
{'id':1, 'name':'jhon doe', 'email':'jhondoe#example.com'}
in your backend file you need to call
req.body.id not req.user._id

Resources