how to remove an object inside the array of objects in mongodb - javascript

I want to remove an object inside the array of objects and I am doing this
router.post("/delVendAttach", async (req, res) => {
try {
let vend = await Vendors.findOneAndUpdate({ "level1.email": req.body.email }, {
$pull: {
"level2.attachments": {
_id: req.body.id
}
}
})
return res.status(200).send("Attachment Deleted Successfully");
} catch (error) {
console.log("error", error);
return res.status(400).send(error);
}
});
Here is the img of db collection

I think you find from level1.email and remove from level2 that the problem.
Try below code may be works for you !
let vend = await Vendors.findOneAndUpdate({ "level1.email": req.body.email }, {
$pull: {
"level1.attachments": {
_id: req.body.id
}
}
})

Duplicate of Using $pull in Mongodb to remove a deeply embedded object

Related

Node Js: Remove string array element from mongoDB

I have a user schema as follows:
const UserSchema = new mongoose.Schema({
skills: [String]
});
module.exports = mongoose.model("User", UserSchema);
And a Fetch request to delete a skill as follows:
const deleteItem = async (id) => {
try {
await fetch(`http://localhost:5000/api/user/deleteskill`, {
method: "DELETE",
headers: { "Content-Type": "application/JSON", token: accessToken },
body: JSON.stringify({ userid: userid , skill:id}),
})
.then((res) => res.json())
.then((data) => {
console.log("USER SKILLS:", data.userskills);
});
} catch (err) {
console.log(err);
}
};
Server
const deleteSkill = async (req, res) => {
try {
const user = await User.findById(req.body.userid)
//user.skills.pull(req.body.skill);
// removeskill = user.skills.filter(function(item) {
// return item !== req.body.skill
// })
if (user.skills.includes(req.body.skill)) {
res.status(400).json("Item Still Exists");
} else {
res.status(200).json("Item Deleted");
}
} catch (error) {
res.status(500).send({ error: error.message });
}
};
the array is in the following structure
[
'skill1', 'java', 'skill5'
]
I have tried to remove the user skill from the array in several ways but I still get res.status(400).json("Item Still Exists");. What I'm doing wrong?
Use the findOneAndUpdate method to find a document with the user id and update it in one atomic operation:
const deleteSkill = async (req, res) => {
try {
let message = "Item Deleted";
let status = 200;
const user = await User.findOneAndUpdate(
{ _id: req.body.userid },
{ $pull: { skills: req.body.skill } },
{ new: true }
)
if (user && user.skills.includes(req.body.skill)) {
message = "Item Still Exists";
status = 400;
} else if (!user) {
message = "User Not Found";
status = 404;
}
res.status(status).send({ message });
} catch (error) {
res.status(500).send({ error: error.message });
}
};
I believe you want to remove skills from the database then the following function could help you out.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { userid: userid, skillid: skillid};
dbo.collection("skills").deleteOne(myquery, function(err, obj) {
if (err) throw err;
console.log("1 document deleted");
db.close();
});
});
You have a method of removing elements from arrays, if you want to remove the first one you could use array.shift (more on it here), but if you want to delete it completely from your database you could always, find it and then update it.
User.update({ _id: userid }, { $pull: { "skills": "[skill]" }})

Node JS throwing cannot set headers after they are sent to the client, after using mongoose.removeOne

I have a method that deletes products and before it does it check if the user who is trying to delete the product is the user who created it. When i execute it with Insomnia it successfully removes the product but i get an error on the console saying cannot set headers after they are sent to the client.
My method:
exports.deleteProduct = (req, res) => {
const id = req.params.productId;
Product.deleteOne({ _id: id, userId: req.user._id }, () => {
return res.status(401).json("Not authorized");
})
.then(() => {
return res.status(200).json("Product deleted");
})
.catch((err) => {
return res.status(500).json({
error: err,
});
});
};
I'm pretty sure this is happening because I'm chaining a .then() and .catch() after executing it.
I tried to do this but it didn't work because the err parameter that I'm sending to the callback function is null.:
exports.deleteProduct = (req, res) => {
const id = req.params.productId;
Product.deleteOne({ _id: id, userId: req.user._id }, (err) => {
if (err) {
return res.status(401).json("Not authorized");
}
return res.status(200).json("Product deleted");
});
};
When i tried this second approach I always got the 200 status, meanwhile the product didn't delete.
Any idea how to deal with this?
You can try something like this:
Product.deleteOne({ _id: id, userId: req.user._id }, (err, result) => {
if(err) {
return "something"
}
return "something else"
});
or: in async / await way
try {
await Product.deleteOne({ _id: id, userId: req.user._id });
} catch (err) {
// handle error here
}
By the way, why you are passing userId at the deleteOne method?

Inability to pull from a nested array

I have this query
router.delete('/:_id', async (req, res) => {
const {_id} = req.params;
const errors = [];
console.log(_id);
await Promise.all([
// Pon.findOneAndDelete({_id}).catch((e) => {
// console.log(e);
// errors.push('Something went wrong. Pon was not deleted');
// }),
// ^^^^^^^^^ this part worked. Wanted to just test the other query
User.findOneAndUpdate({_id: req.user._id}, {$pull: {pons: {_id}}}).catch((e) => {
console.log(1, e);
errors.push('Something went wrong. Pon reference was not deleted from user');
}),
]);
if (errors.length > 0) {
console.log(2, errors);
res.json({ok: false, errors});
} else {
res.json({ok: true});
}
});
I am just trying to remove an element from user object. Here's the object
{
"_id": {
"$oid": "5ea2d8cffe35b93e84f7962b"
},
"pons": [
{
"$oid": "5ea98b181a2be04ec87aa710" // this is what I want to remove
}
],
"email": "test#test.tes",
"password": "$2a$12$VJ0MkcGUs42pikT42qLpyOb0Sd53j9LXH8dY9RdR/GcmUVzJoP8gi",
"__v": 0
}
This query doesn't throw any errors, catch doesn't catch anything, so I don't know what I'm doing wrong. I tried just doing {pons: _id} instead of {pons: {_id}} but no luck.
The _id is correct. Checked with console.log.
What am I missing?
_id is just a String. If you want to match an ObjectId, you have to wrap it like this mongoose.Types.ObjectId(_id)
const ObjectId = mongoose.Types.ObjectId
User.findOneAndUpdate(
{ _id: ObjectId(req.user._id) },
{ $pull: { pons: ObjectId(_id) } }
)
Since you are querying by _id, you could also use User.findByIdAndUpdate() which will wrap req.user._id with ObjectId for you.
const ObjectId = mongoose.Types.ObjectId
User.findByIdAndUpdate(req.user._id, { $pull: { pons: ObjectId(_id) } })

CRUD : How to delete a product category with all products inside?

I need to delete a product category, with all products inside. In Product model, category is an object reference.
Is there a simple way, some known method ?
I tried removeAll, it says removeAll is not a function.
router.delete(`/category/:id/delete`, async (req, res) => {
try {
if (!req.params.id) res.send("missing id");
else {
await Product.removeAll({ category: req.params.id });
const categoryToDelete = await Category.findById(req.params.id);
await categoryToDelete.remove();
res.send("category deleted");
}
} catch (error) {
res.status(400).json({ error: error.message });
}
});
thanks for your knowledge and help
router.delete(`/category/:id/delete`, async (req, res) => {
try {
if (!req.params.id) res.send("missing id");
else {
await Product.remove({ category: req.params.id });
res.send("category deleted");
}
}
} catch (error) {
res.status(400).json({ error: error.message });
}
});
simply pass the query into the remove method, this will remove all matching documents

Mongoose - remove array element in update

I have a JSON in this format:
{
_id:5522ff94a1863450179abd33,
userName:'bill',
__v:3,
friends:[
{
_id:55156119ec0b97ec217d8197,
firstName:'John',
lastName:'Doe',
username:'johnDoe'
},
{
_id:5515ce05207842d412c07e03,
lastName:'Adam',
firstName:'Foo',
username:'adamFoo'
}
]
}
And I would like to remove whole corresponding subarray. For example I want to remove user John Doe with ID 55156119ec0b97ec217d8197 so the result will be:
{
_id:5522ff94a1863450179abd33,
userName:'bill',
__v:3,
friends:[
{
_id:5515ce05207842d412c07e03,
lastName:'Adam',
firstName:'Foo',
username:'adamFoo'
}
]
}
So far I have this:
exports.delete = function (req, res) {
var friends = req.friends[0];
friends.update(
{'_id': req.body.friendsId},
{$pull: {'friends.friends': {_id: req.body.friendId}}}, function (err) {
if (err) {
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
res.json(friends);
}
});
};
But without result and also I'm not getting any error, it will stay just same as before. req.body.friendsId is ID of main array and req.body.friendId is ID of specific user which I want to pull.
Change your update query to this:
exports.delete = function (req, res) {
var friends = req.friends[0]; // assuming the friends object is your mongodb collection
friends.update(
{ '_id': req.body.friendsId },
{ $pull: {'friends': { _id: req.body.friendId } } }, function (err) {
if (err) {
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
res.json(friends);
}
});
};
This will search for documents which have the friends array element _id value = req.body.friendsId and removes the specific array element from that array using the $pull operator.

Categories

Resources