how can send new added item in nested object as response - node.js

I have a collection with name User in my mongodb for the example you can see in below a sample of saved user
{
_id: new ObjectId("61488f3892099143ca2b2bbc"),
name: 'test',
orders: [],
products: [
{
name: 'as',
image: '049fcd8d-f954-4aef-bd77-757af881f7c5.jpeg',
_id: new ObjectId("61531666ad63a47ed692c90b")
},
]
}
I have function with node.js that has responsible to add new product to selected user
async function addProduct(req, res, next) {
await User.findOneAndUpdate(
{ _id: req.params.userId },
{
$addToSet: {
products: {
...req.body,
image: req.file.filename,
},
},
}
);
return res.status(200).send();
}
but I want to send only new added product as response
please help me to solve this problem.

I recommend you to use the $push operator (doc):
{ $push: { <field1>: <value1>, ... } }
Using it with your example:
(async () => {
await User.findByIdAndUpdate(
'6153769ce997d65baf860cc7',
{
$push: {
products: {
name: 'as2',
image: '589fcd8d-f954-4aef-bd77-757af881f7c5.jpeg'
}
}
}
);
})();

Related

How to delete an object in nested array of objects in MongoDB with node js

I'm still a beginner in node express js and mongoDB. Right now, I'm trying to Delete an object in nested array of objects.
Array of Objects:
[{
_id: new ObjectId("63d89f8823981819cf61816e"),
iqc: [
{
partname: 'jio',
vendorname: 'jio',
partcode: '1234',
grndate: '2023-01-10',
project: 'jio',
lotqty: '200',
failurerate: '15%',
issuedetails: 'damaged',
status: 'pending',
_id: new ObjectId("63d89f8823981819cf61816f")
},
{
partname: 'sky',
vendorname: 'sky',
partcode: '5678',
grndate: '2023-01-04',
project: 'sky',
lotqty: '300',
failurerate: '20%',
issuedetails: 'damaged',
status: 'pending',
_id: new ObjectId("63d89f8823981819cf618170")
}
],
__v: 0
}]
I want to delete the object in iqc which has the _id: new ObjectId("63d89f8823981819cf618170").
So i tried this code for deleting in node js. It didnt work.It throws an error data.iqc.findByIdandDelete is not a function
app.delete('/delete/:id/:secondid', async (req, res) => {
const data = await IQC.findById(req.params.id);
if(data )
{
await data.iqc.findByIdandDelete(req.params.secondid)
return res.json("Deleted Successfully")
}
});
Here IQC is the db collection and secondid is the id of the nested object id which I wanted to delete _id: new ObjectId("63d89f8823981819cf618170").
Thanks in Advance.
You don't need to delete but update using $pull because you are updating the array (removing the object).
So you can try something like this
yourModel.update({
"iqc._id": req.params.id
},
{
"$pull": {
"iqc": {
"_id": req.params.id
}
}
})
Example here
I figured it out. This should be working in NodeJS. No problemo.
app.delete('/delete/:id/:secondid', async (req, res) => {
await IQC.findOneAndUpdate(
{
_id: req.params.id
}, {
$pull: {
iqc: {
_id: req.params.secondid
}
}
}
)
}

mongoose findOneAndUpdate gives different user

I was trying to $pull an object inside my cart collections. but after I make a request and sent a specific _id it gives me a different person.
this was the _id I sent from my client side.
{ id: '62a849957410ef5849491b1b' } /// from console.log(req.params);
here's my mongoose query.
export const deleteItem = (req,res) => {
const { id } = req.params;
console.log(id);
try {
if(!mongoose.Types.ObjectId.isValid(id)) return res.status(404).json({ message: 'ID not found' });
ClientModels.findOneAndUpdate(id, {
$pull: {
cart: {
product_identifier: req.body.cart[0].product_identifier
}
}
},{
new: true
}).then(val => console.log(val)).catch(temp => console.log(temp));
} catch (error) {
res.status(404).json(error);
}
}
after the request here's the callback.
{
_id: new ObjectId("62a77ab16210bf1afd8bd0a9"),
fullname: 'Gino Dela Vega',
address: '008 Estrella.st santo cristo',
email: 'gamexgaming1997#gmail.com',
google_id: 'none',
birthday: '1997-12-30',
number: 9922325221,
gender: 'Male',
username: 'ginopogi',
password: '$2b$12$YCc1jclth.ux4diwpt7EXeqYyLOG0bEaF.wvl9hkqNVptY.1Jsuvi',
cart: [],
wishlist: [],
toBeDeliver: [],
Delivered: [],
__v: 0
}
as you guys can see after sending a specific _id to find a user...the callback gives me a different user reason that I can't pull the specific object inside cart. (the object I was trying to pull is on another user)
Probably because findOneAndUpdate expect a filter as first parameter, try to switch to findByIdAndUpdate if you want to filter by a specific _id:
export const deleteItem = (req, res) => {
...
ClientModels.findByIdAndUpdate(
id,
{
$pull: {
cart: {
product_identifier: req.body.cart[0].product_identifier,
},
},
},
{
new: true,
}
)
.then((val) => console.log(val))
.catch((temp) => console.log(temp));
} catch (error) {
res.status(404).json(error);
}
};

mongoose delete from array

I need to remove the user's id from all objects in the collection except the one that was passed, in my example it is value: 'Тата', tell me how to make such a request?
console.log(result)
[
{
_id: 5fa702b2f18e5723b4c00d9f,
value: 'Тата',
vote: { '36e7da32-f818-4771-bb5e-1807b2954b5f': [Array] },
date: 2020-11-07T20:25:22.611Z,
__v: 0
}
]
console.log(req.body)
{ value: 'Тата', habalkaId: '36e7da32-f818-4771-bb5e-1807b2954b5f' }
console.log(req.user._id)
5f63a251f17f1f38bc92bdab
that's all I could do, just find
router.post('/', passport.authenticate('jwt', {session: false}), (req, res) => {
FirstName.find({value: req.body.value})
.then(result => {
if (result.length) {
console.log(result)
console.log(req.body)
console.log(req.user._id)
FirstName.find({value: {$ne: 'Слоник'}}, function (err, arr) {
arr.map(e => {
if (e.vote[req.body.habalkaId].length) {
if(e.vote[req.body.habalkaId].includes(String(req.user._id))){
console.log(e.vote[req.body.habalkaId])
}
}
})
})
} else {
new FirstName({
value: req.body.value,
vote: {[req.body.habalkaId]: [String(req.user._id)]}
}).save();
}
})
// res.json({res: req.body})
})
FirstName.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const FirstNameSchema = new Schema({
value: {
type: String
},
vote: {
type: Object
},
date: {
type: Date,
default: Date.now
}
});
module.exports = FirstName = mongoose.model('firstname', FirstNameSchema);
If I've understand well, you want something like this:
db.collection.update({
"value": {
"$ne": "tata"
}
},
{
"$pull": {
"vote.array_name": "id_value"
}
},
{
multi: true
})
First of all, find all document that not match the value with the given one. Then, for each document found, delete the object from the array, using $pull where the id given matches.
Example here
Please check the payground and check if I've used the correct schema and it shows the expected output.

Trying to update a subdocument in a parent document mongoose

i am trying to update or remove a subdocument from a parent document using mongoose.
My code:
editSubscription(req, res) {
const token = req.headers.authorization;
jwt.verify(token, req.app.get('yourSecretKey'), function (err, payload) {
userModel.update({ _id: payload.user._id, "subscriptions._id": req.params.id }, { "$set": { "subscriptions.$": req.body } }, function (err, obj) {
console.log(obj)
})
})
}
The output of the console.log is
{ n: 0, nModified: 0, ok: 1 }
How should i do this? i know if its modified the nModified returns a 1. I can't find any docs on how to approach this or solve it and all the solutions here on stackoverflow i already tried, nothing is working.
A sample of a document in my collection:
id: '5db990daa05aa90de0c8b86b',
user:
{ role: 'User',
subscriptions: [
{ active: true,
_id: '5dbad05aaf232e2bdc033339',
name: 'Basic Fit',
price: 20,
paymentDate: '07-11-2020',
created: '2019-10-31T12:15:22.360Z',
updated: '2019-10-31T12:15:22.360Z' },
{ active: true,
_id: '5dbad2568bf56255a0f39bc7',
name: 'Netflix',
price: 10,
paymentDate: '07-11-2019',
created: '2019-10-31T12:23:50.141Z',
updated: '2019-10-31T12:23:50.141Z' } ]
],
_id: '5db990daa05aa90de0c8b86b',
fullname: 'Test naam',
email: 'test1#mail.com',
password:
'$2a$10$VzBnIcVraIRdmzy6rPHOX.7gGOXToTBNISLEfi429OfpRx02FxCaO',
birthDate: '02-12-1988',
created: '2019-10-30T13:32:10.276Z',
updated: '2019-10-30T13:32:10.276Z',
__v: 0 },
payload.user._id == the verified logged in user ID
req.params.id is supposed to be the subscriptionId im trying to edit
Try this:
editSubscription(req, res) {
const token = req.headers.authorization;
jwt.verify(token, req.app.get('yourSecretKey'), function (err, payload) {
userModel.update({ _id: ObjectId(payload.user._id), "subscriptions._id": ObjectId(req.params.id) }, { "$set": { "subscriptions.$": req.body } }, function (err, obj) {
console.log(obj)
})
})
}
I tried and im getting a 500 error response back..
When i remove the 'req.params.id' and i do it like this:
userModel.updateOne({ _id: payload.user._id }, { "$set": { "subscriptions.0.price":
req.body.price} }).then(user => {
console.log(user)
}).catch(err => {
console.log(err)
})
Then it works but since i have multiple items in an array i do not want to update only the first one..
I tried using a filter in the $set operator but im getting errors all over the place..

Updating two different documents in one line

I have the following code for updating two users, both with different id .
User.update(
{ id: req.body.myId },
{
$addToSet: { FriendIds: req.body.friendId }
},
function(err, user){
}
);
User.update(
{ id: req.body.friendId },
{
$addToSet: { FriendIds: req.body.myId }
},
function(err, user){
}
);
I could not find anything in the docs aside from updating two things with the same attribute by setting multi : true . However, the ids are different in this case, and it would be easier to error handle if I had them both being updated at once.
Why not take advantage of parallel operations in bluebird or using co
You can do something like :
co(function* () {
var res = yield {
1: User.update({ id: req.body.myId }, { $addToSet: { FriendIds: req.body.friendId }}).exec(),
2: User.update({ id: req.body.friendId },{$addToSet: { FriendIds: req.body.myId }}).exec(),
};
console.log(res); // { 1: Upate_response_for_1 , 2: Upate_response_for_2 }
}).catch(onerror);

Resources