Mongo/Mongoose field value aren't updated - node.js

I have a problem with my MongoDB collection. If i try to replace field in my item it won't get saved. It logs new value correctly, but nothing in DB really changes. What's wrong here?
exports.update = function (req, res) {
const { entryid, userid } = req.params;
let field;
['stop', 'description'].forEach(item => req.query[item] ? field = item : -1);
db.TimeEntry.findById(entryid).then(function (entry) {
(req.query[field] === undefined) ? entry[field] = 'no value specified' : entry[field] = req.query[field];
console.log('v:', entry[field]);
entry.save(function (err) {
if (err) console.log(err);
db.TimeEntry.find({ userId: userid })
.then(foundEntries => res.status(200).json(foundEntries));
});
}).catch(err => console.log(err));
}
Schema:
const mongoose = require('mongoose');
const TimeEntrySchema = new mongoose.Schema({
start: {
type: mongoose.Schema.Types.Mixed,
default: Date.now,
required: true
},
stop: mongoose.Schema.Types.Mixed,
description: String,
project: String,
billable: Boolean,
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
}
}, { timestamps: true })
TimeEntrySchema.pre('remove', function (next) {
User.findById(this.userId).then(user => {
user.entries.remove(this.id);
user.save().then(function (e) {
next();
}).catch(err => console.log(err));
})
});
const TimeEntry = mongoose.model('TimeEntry', TimeEntrySchema);
module.exports = TimeEntry;
Edit: Modified this way, still no effect.
` entry[field] = (!req.query[field]) ? 'TESTINGTESTING' : req.query[field];
entry.markModified('description');
console.log('v:', entry[field]);
entry.save().then(function (err) {`
Final edit: Ok so this is the final solution.
exports.update = function (req, res) {
const { entryid, userid } = req.params;
let field;
['stop', 'description'].forEach(item => req.query[item] ? field = item : -1);
db.TimeEntry.update({ _id: entryid }, {
$set: {
description: req.query[field] || 'no value specified'
}
}).then(function () {
db.TimeEntry.find({ userId: userid })
.then((foundEntries) => res.status(200).json(foundEntries))
}).catch(err => console.log(err));
}

Try using .update:
return db.TimeEntry.update({ _id: entryid }, {
$set: {
[field]: req.query[field] || 'no value specified'
}
}
}).then(() => db.TimeEntry.find({ _id: entryid }))
.then((resultEntries) => res.status(200).json(foundEntries))

Have you tried this: entry.save().exec(callbackFN);
instead of entry.save(callbackFN); ?

Related

cant update in mongoDb with mongoose

I am trying to create a followers/following function in my project. However I cannot seem to update the DB correctly. I'm able to send the ids as they both print when I console.log but nothing in my DB updates and I do not get any response in my frontend.
route
app.put('/api/follow', async function (req, res, next){
const { id } = req.query;
const userFrom = req.body.data
console.log('OTHER USER ID',id)
console.log('CURRENT ID', userFrom)
User.findByIdAndUpdate(id), {
$push:{followers:req.body.data}
},{new:true},
(err,result)=>{
if(err) {
if(err) return res.status(400).send(err)
}
User.findByIdAndUpdate(req.body.data), {
$push:{following:id}
},{new:true}.then(result=> {
res.json(result)
}).catch(err=>{
return res.status(422).json({error:err})
})
}
})
user model
const mongoose = require("mongoose");
const User = mongoose.model(
"User",
new mongoose.Schema({
username: String,
email: String,
password: String,
phoneNo: String,
bio: String,
filePath: String,
following: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
],
followers: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
})
);
module.exports = User;
my route end function
const clickHandler = () => {
const currentID = currentUser.id;
const id = this.props.id;
console.log('CURRENT ID',currentID)
console.log('otherUserID',id)
Axios.put(`http://localhost:8080/api/follow/?id=${id}`, { data: currentID }, { headers: authHeader() })
.then(response => {
if (response.data.success) {
console.log('FOLLOWED', response.data)
// this.setState({ userDetails: response.data.details })
} else {
alert('Error')
}
})
}
This should be
User.findByIdAndUpdate(id, {
You should not close the bracket after id but after new: true})

Tools to create a functional Shopping Cart

I'm creating an e-commerce using Reactjs for frontend and Nodejs for backend (also express), and i want to create an shopping cart "connected" to the user account, where the user can recharge the page, close it, and the cart doesn't reset.
I'm looking for tools to create this, or some tutorial to do it with node-express, thanks! (i don't have code yet, cause i don't know from where starts)
This is User Model with Cart( with add-to-cart and remove from cart Function )
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
resetToken: String,
resetTokenExpiration: Date,
cart: {
items: [
{
productId: {
type: Schema.Types.ObjectId,
ref: "Product",
required: true,
},
quantity: {
type: Number,
required: true,
},
},
],
},
});
userSchema.methods.addToCart = function (product) {
const cartProductIndex = this.cart.items.findIndex((cp) => {
return cp.productId.toString() === product._id.toString();
});
let newQuantity = 1;
const updatedCartItems = [...this.cart.items];
if (cartProductIndex >= 0) {
newQuantity = this.cart.items[cartProductIndex].quantity + 1;
updatedCartItems[cartProductIndex].quantity = newQuantity;
} else {
updatedCartItems.push({
productId: product._id,
quantity: newQuantity,
});
}
const updatedCart = {
items: updatedCartItems,
};
this.cart = updatedCart;
return this.save();
};
userSchema.methods.removeFromCart = function (productId) {
const UpdatedCartItems = this.cart.items.filter((item) => {
return item.productId.toString() !== productId.toString();
});
this.cart.items = UpdatedCartItems;
return this.save();
};
userSchema.methods.clearCart = function () {
this.cart = { items: [] };
return this.save();
};
module.exports = mongoose.model("User", userSchema);
Here, Routes
router.get("/cart", (req, res, next) => {
req.user
.populate("cart.items.productId")
.then((user) => {
const products = user.cart.items;
// console.log(products);
res.render("home/cart", {
path: "/cart",
pageTitle: "Your cart",
products: products,
isAuthenticated: req.session.isLoggedIn,
});
// console.log(products);
})
.catch((err) => {
console.error(err);
});
});
router.post("/cart",(req, res, next) => {
const prodId = req.body.productId;
// console.log(prodId);
Product.findById(prodId)
.then((product) => {
return req.user.addToCart(product);
})
.then((result) => {
// console.log(result);
res.redirect("/cart");
});
});
Tech:-
Frontend:- Ejs View Engine
Backend:- Express, MongoDB Atlas

I get a save() is a not a function error mongoose

exports.clearHours = (req, res, next) => {
Hour
.find({ user: req.body.userId })
.then(hour => {
for (let i=0;i<hour.length;i++) {
hour[i].hours = 0;
}
return hour.save()
})
.then(result => {
res.status(200).json({message: 'Working hours have been successfully updated.'});
})
.catch(err => {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
})
};
I am trying to save the formatted array on the database and I get this error. The updated code is passed properly but when I am trying to save the array it comes up with this error. Any ideas why?
This is my hour model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const hourSchema = new Schema ({
day: {
type: String,
required: true
},
hours: {
type: Number,
required: true
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
});
module.exports = mongoose.model('Hour', hourSchema);
It seems you are fetching the document into memory and re-setting the hour field to 0, better you can run an update query into the database itself.
On top require mongoose -
const mongoose = require('mongoose');
Below is clearHours method refactored.
exports.clearHours = async (req, res, next) => {
try {
const query = {
user: mongoose.Types.ObjectId(req.body.userId)
};
const update = {
$set: {
hours: 0
}
};
await Hour.update(query, update).exec();
res.status(200).json({message: 'Working hours have been successfully updated.'});
} catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};

Updating DB Shema in Express JS with Mongoose library

I have created a Mongo DB schema with Mongoose in Express.js and I am building the REST API. However when I try to update existing records the values that I do not update from the schema automatically become null. I understand why this happens just not sure exactly how it should be coded.
This is the route:
router.patch("/:projectId", async (req, res) => {
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
{
$set: {
title: req.body.title,
project_alias: req.body.project_alias,
description: req.body.description
}
}
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
also here is the schema:
const ProjectsSchema = mongoose.Schema({
title: {
type: String,
required: true,
unique: true
},
project_alias: {
type: String,
unique: true,
required: true
},
description: String,
allowed_hours: Number,
hours_recorded: {
type: Number,
default: 0
},
date_added: {
type: Date,
default: Date.now
}
});
My problem is that when I want to update just the title:
{
"title" : "Title Updated33"
}
description and alias become null. Should I implement a check?
Just use req.body for the update object like this:
router.patch("/:projectId", async (req, res) => {
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
req.body
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});
Or even better, create a helper function like this so that we can exclude the fields in the body that doesn't exist in the model:
const filterObj = (obj, ...allowedFields) => {
const newObj = {};
Object.keys(obj).forEach(el => {
if (allowedFields.includes(el)) newObj[el] = obj[el];
});
return newObj;
};
router.patch("/:projectId", async (req, res) => {
const filteredBody = filterObj(
req.body,
"title",
"project_alias",
"description",
"allowed_hours",
"hours_recorded"
);
try {
const updatedProject = await Project.updateOne(
{ _id: req.params.projectId },
filteredBody
);
res.json(updatedProject);
} catch (err) {
res.json({ message: err });
}
});

mongoose only insert id, createdAt and updated fields

I'm learning to use Node.js and MongoDB. I have a problem when I try to save data to the database.
Here's my code
const Test = require('../models/test');
const test = (req, res, next) => {
let url = "http://localhost:3000/article"
request(url, (req, (err, fields) => {
if (err) {
return res.status(400).json({
error: "error"
})
}
var objTest = JSON.parse(fields.body);
console.log(objTest.user)
let test = new Test(objTest)
console.log("ini",test)
test
.save()
.then(result => {
res.send(result)
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
}))
}
here my Test Schema
const testSchema = new mongoose.Schema(
{
tittle: {
type: String,
index: true,
},
content: {
type: String,
},
postedBy: { type: mongoose.Schema.ObjectId, ref: 'Author' },
created: {
type: Date,
default: Date.now,
},
},
{
timestamps: true,
},
);
module.exports = mongoose.model('Test', testSchema, 'tests');
The response in Postman is only id, createdAt and updatedAt. Thank you.

Resources