How to save the user document when creating a new post? - node.js

So, I have figured out the previous problems and just need to populate the user document with posts. Currently user document looks like this:
{
"posts": [],
"_id": "5e75cf827ef14514f69c6714",
"username": "dio",
"email": "dio123#gmail.com",
"password": "$2b$10$fwV.KaZG.5tjtmMxQ9NNE.7.XAh6pzLFgf85z9BpPVOgFguR2inGO",
"createdAt": "2020-03-21T08:25:38.459Z",
"updatedAt": "2020-03-21T08:25:38.459Z",
"__v": 0
}
So, I did this while creating the post to be able to populate it later.
newPost: (req, res) => {
const data = {
title: req.body.title,
content: req.body.content,
user: req.user.userId
}
Post.create(data, (err, newPost) => {
console.log(data, "data")
if (err) {
return res.status(500).json({ error: err })
} else if (!newPost) {
return res.status(400).json({ message: "No Post found" })
} else if (newPost) {
User.findById(req.user.userId, (err, user) => {
user.Posts = user.Posts.concat(newPost._id)
return res.status(200).json({ newPost, user })
})
}
})
}
After doing this when i return user from the above return statement, it looks like this:
{
posts: [ 5e75d89fa048e321f704453b ],
_id: 5e75cf827ef14514f69c6714,
username: 'dio',
email: 'dio123#gmail.com',
password: '$2b$10$fwV.KaZG.5tjtmMxQ9NNE.7.XAh6pzLFgf85z9BpPVOgFguR2inGO',
createdAt: 2020-03-21T08:25:38.459Z,
updatedAt: 2020-03-21T08:25:38.459Z,
__v: 0
}
Everytime I create a new post, I exprect the posts array to contain the objectIDs of the posts that the user has just created, but it's only pushing the latest post's objectId. Why does it not remembering the previous ones?
Also, I want to get the user's posts:
getUserPosts: async (req, res) => {
try {
const user = await User.findById(req.params.id).populate("posts");
if (!user) {
return res.status(400).json({ error: "No user" });
}
return res.status(200).json({ userPosts: user.posts });
} catch (err) {
return res.status(500).json({ error: "Server error" });
}
}
Since, the user document saved in the database has empty array of posts I am not able to populate it. Please help.

After you add the new post's id to the user's posts array, you need to save the user:
Post.create(data, (err, newPost) => {
console.log(data, "data");
if (err) {
return res.status(500).json({ error: err });
} else if (!newPost) {
return res.status(400).json({ message: "No Post found" });
} else if (newPost) {
User.findById(req.user.userId, (err, user) => {
user.posts.push(newPost._id);
user
.save()
.then(() => {
return res.status(200).json({ newPost, user });
})
.catch(err => {
return res.status(500).json({ error: err });
console.log(err);
});
});
}
});
As I remember in your previous questions, the name of the field for posts was posts not Posts in the user schema, so the following line is important, also we use push method instead of concat:
user.posts.push(newPost._id);
After this, we just need to save the user with save method, since save method returns a promise I added then catch blocks.

SuleymanSah's answer is correct. However, be aware of the safer version:
User.update(
{ _id: req.user.userId },
{ $push: { userPosts: newPost._id } },
done
);
The reason behind this is that a modification might occur on the user between the find and the save whereas the $push is an atomic operation.

Related

How to Remove more than one documents from mongodb

I am trying to deleteFeature meanwhile i want all the comments related to that feature deleted but i don't know how to do it.
my deleteFeature method -
exports.deleteFeature = (req, res) => {
try {
const { slug } = req.params;
Feature.findOne({ slug: slug.toLowerCase() }).exec((err, feature) => {
if (err) {
return res.status(400).json({
error: errorHandler(err),
});
}
console.log("Test");
Comment.deleteMany({ _id: feature._id });
console.log("chest");
feature.remove();
console.log("Best");
return res.json({
message: "Your Feature has been Deleted Successfully",
});
});
} catch (error) {
return res.status(400).json({
error: error,
});
}
};
I have this on comment model -
feature: {
type: ObjectId,
ref: "Feature",
required: true,
},
So when i delete a feature, i want to delete all the comments containing that feature's _id on that feature field
Change
Comment.deleteMany({ _id: feature._id });
to
Comment.deleteMany({ feature: feature._id });

Why booleans always update false?? (Moongose)

I would like to knwo why using the Query findOneAndUpdate, overwrite some data and donĀ“t update booleans, always are false.
exports.userUpdateInterest = (req, res) => {
let keys = Object.keys(req.body);
if (keys.indexOf('email') > -1) {
User.findOne({
email: req.body.email
}).exec(async (err, user) => {
console.log("execuser",user)
const update = {
onboarding: req.body.onboarding,
oneToOne: req.body.oneToOne,
nps: req.body.nps,
questions: req.body.questions,
comunication: req.body.comunication
};
try {
let document = await User.findOneAndUpdate(
{ email: user.email },
update,
{ returnOriginal: false }
);
console.log("res", document)
res
.status(200)
.send({ message: 'User update success!', user: document });
console.log("res", document)
} catch (error) {
res.status(500).send({ message: 'User update fail!' });
}
});
}else{
res.status(400).send({ message: 'Missing email field!'})
}
};
I have try to change de query and nothing is working, at least, on my unless knowment. Any help please?

Replacing previous array of objects with new array of objects using express/mongoose

I am trying to update the favourite stations array in my database, however I just can't seem to be able to update it? I have searched for ages to try and find a solution, but nothing seems to work.
I have the ID saved in the cookie, and am sending that in the body when the update request is made...
"selected" is an array of objects. this is what will need replace the contents of the to the favouriteStations property, or add it if it is empty.
the database structure is like this:
"id": id,
"email: "test#test",
"password": "test",
"userInfo": {
"firstName": "test",
"lastName": "test",
"favouriteStations": [{array i want to replace}]
}
i have tried many different combinations, however this is what i have so far, and it doesnt work
app.post("/api/update", (req, res) => {
console.log("updating user details");
const { id, selected } = req.body;
UserModel.findOneAndUpdate(
{ _id: id },
{ userInfo: { favouriteStations: { $set: selected } } },
{ useFindAndModify: false }
)
.then((user, err) => {
if (err) {
console.log("an error?");
res.status(500).json({
error: "Server error",
});
} else if (!user) {
console.log("user not exists?");
res.status(401).json({
error: "Incorrect credentials",
});
} else {
console.log("updated?");
console.log(user);
}
})
.catch((err) => {
console.log(err);
});
});
It is unclear as to what you mean by ".. it doesn't work", can you elaborate please i.e. what errors do you receive? If none, what does happen?
The $set operator should be used in the following form, from MongoDB docs:
{ $set: { <field1>: <value1>, ... } }
In saying that, you may not be accessing favouriteStations correctly, use dot-notation to access the subdocument as follows:
...
UserModel.findOneAndUpdate(
{ _id: id },
{ $set: {'userInfo.favouriteStations': selected} } ,
{ useFindAndModify: false }
)
...

How to update object in array of object of a document in mongoose?

My User Schema is like this
{
_id:ObjectId("6e9465528a15ba6")
name: 'XYZ',
email: 'abc#gmail.com',
transactions: [
{
_id:ObjectId("5e946557a5128a15ba6"),
date: 2020-04-09T06:00:30.000Z,
type: 'type1',
category: 'category1',
description: 'some desc',
}
]
}
I want to update some fields of transaction with specific id. But not happening.
I tried the solution answered to
Mongoose, update values in array of objects this question.
May be my _id is of type ObjectId and id coming from my request is String?
So how can I solve this problem?
My code is like this but still getiing error user.transactions._id is not function
app.post('/api/update', function (req, res) {
const {
id,
email,
date,
type,
category,
description
} = req.body;
User.findOne({email}, function (err, user) {
if (err) {
console.error(err);
res.status(500)
.json({
error: 'Internal error please try again'
});
} else if (!user) {
res.status(401)
.json({
error: 'Incorrect email or password'
});
} else {
const objectId = mongoose.Types.ObjectId(id);
let transaction = user.transactions._id(objectId);
transaction.date = date;
transaction.type = type;
transaction.category = category;
transaction.description = description;
user.save((err, data) => {
if (err) return res.send(err);
return res.sendStatus(200);
});
}
});
});
fortunately I had to do something similar recently, so I suggest you to have a look at this page from Mongoose docs in the case I miss something, but basically you have to find the document first and then update its array of objects.
I'd try something like this:
User.findOne({ _id: your_user_id }, (err, data) => {
if (err) return console.log(err);
if (data) {
//Mongoose has a special method (id) for subdocuments
var transaction = data.transactions.id(your_transaction_id);
date: new Date(),
type: 'type2',
category: 'category2',
description: 'whatever',
//data.save() saves everything, document and subdocument
data.save((err, data) => {
if (err) return console.log(err);
done(null, data);
});
}

User.findOneAndUpdate not returning the updated user object

This is my updateUser controller function. It's not returning the updated object, even after setting {new: true} and {useFindAndModify: false} in the MongoDB connection in app.js. I'm only getting the same object whose id I am passing through the params.
updateUser: (req, res) => {
console.log(req.params, "update user")
User.findOneAndUpdate(req.params.id, { new: true }, (err, updatedUser) => {
console.log(updatedUser)
if (err) {
return res.status(500).json({ error: "server error" })
} else if (!updatedUser) {
return res.status(400).json({ error: "No user found" })
} else if (updatedUser) {
return res.status(200).json({ user: updatedUser })
}
})
}
You are finding document by id, you are using new set with true to get updated document but where are you updating the document.
There is update object that you need to pass to update the data
Link to docs: https://mongoosejs.com/docs/tutorials/findoneandupdate.html

Resources