Getting a $set error even though i am setting it? - mongodb

chats.post('/approveUser', (req, res) => {
// let regex = new RegExp(req.body.requestId)
Chat.updateOne(
{ 'requests._id': req.body.requestId },
{ $set: {'approved': true} },
{ upsert: true }
)
.then(res => {
console.log('hi')
if (!res) {
res.status(404).send()
} else {
res.status(200).send(res)
}
})
.catch(err => {
console.log(err)
res.status(500).send(err)
})
})
Does anyone see why i'm getting an error? It says:
errmsg: '\'$set\' is empty. You must specify a field like so: {$set: {<field>: ...}}'
req.body.requestId is not undefined. This is the layout of each mongoDB document:
{
"_id":"5cd1f4aceb05c12298779345",
"title":"test 3",
"participants":[
{
"_id":"5cd1f4aceb05c12298779347",
"userEmail":"test#gmail.com"
},
{
"_id":"5cd1f4aceb05c12298779346",
"userEmail":"adam2.cole#northumbria.ac.uk"
}],
"chatType":"publicGroup",
"messages":[
{
"_id":"5cd254b591a0eb1de4a0863c",
"text":"hi",
"from":"test#gmail.com",
"dateTimeSent":"2019-05-08T04:01:57.732Z"
},
{
"_id":"5cd254b591a0eb1de4a0863b",
"text":"hi",
"from":"test#gmail.com",
"dateTimeSent":"2019-05-08T04:01:57.764Z"
}
],
"__v":0,
"requests":[
{
"approved":false,
"_id":"5cd2467891a0eb1de4a08631",
"userEmail":"test2#gmail.com"
}
]
}
The intention is to turn approved of any request to true. I'm failing to see why it won't work. Does anyone else see why?
Thanks.

Related

How to return the a formatted response from a mongo query/projection?

I'm trying to create an API to validate a promocode. I have minimal experience with mongo and the backend in general so I'm a bit confused in what is the best approach to do what I'm trying to accomplish.
I have this PromoCode form in the client. When a user types a promocode I would like for my backend to
verify if the code exists in one of the docs.
if it exists then return that code, the value for that code and the couponId
if the code doesn't exist then return an error.
My db is structured like this. The user will type one of those codes inside the codes: []
{
"_id": {
"$oid": "603f7a3b52e0233dd23bef79"
},
"couponId": "rate50",
"value": 50,
"codes": ["K3D01XJ50", "2PACYFN50", "COKRHEQ50"]
},
{
"_id": {
"$oid": "603f799d52e0233dd23bef78"
},
"couponId": "rate100",
"value": 100,
"codes": ["rdJ2ZMF100", "GKAAYLP100", "B9QZILN100"]
}
My route is structure like this:
router.post('/promoCode', (req, res, next) => {
const { promoCode } = req.body;
console.log('this is the req.body.promoCode on /promoCode', promoCode)
if (!promoCode) {
throw new Error('A promoCode needs to be passed')
}
promoCodesModel
.validatePromoCode(req.body.promoCode)
.then((response) => {
console.log('response inside /promoCode', response)
res.status(200).json({ data: response })
})
.catch((error) => {
res.status(400).json({ result: 'nok', error: error })
})
})
The validatePromoCode function is the following:
const validatePromoCode = async (code) => {
try {
let promoCode = await PromoCodesModel.find(
{"codes": code},
{_id: 0, codes: { $elemMatch: { $eq: code }} })
console.log('This is the promocode', promoCode)
return promoCode
} catch (err) {
throw new Error (err.stack)
}
}
All this seems to sort of work since I get the following response when the code is typed correctly
{
"data": [
{
"codes": [
"COKRHEQ50"
]
}
]
}
when typed incorrectly I get
{
"data": []
}
What I would like to get back is. (How can I accomplish this ?). Thanks
// when typed correctly
{
"data": { value: 50, couponId: "rate50", code: "COKRHEQ50" }
}
// when typed incorrectly
{
"error": "this is not valid code"
}
TL;DR: I would like to return a formatted query with specific values from a mongo query or an error object if that value does not exist on the document object.
Ok just figured it out
To be able to get the this responsed (what I wanted):
{
"data": [
{
"codes": [
"K3D01XJ50"
],
"couponId": "rate50",
"value": 50
}
]
}
I ended up having to do this on validatePromoCode
onst validatePromoCode = async (code) => {
try {
let promoCode = await PromoCodesModel.find(
{ codes: code },
{ _id: 0, codes: { $elemMatch: { $eq: code } }, couponId: 1, value: 1 },
)
return promoCode
} catch (err) {
throw new Error(err.stack)
}
}
But is there a better way on doing this ? Thanks

How can I make a subarray unique

I am having an issue with the following
{
artist:"Macy Gray"
song:"I Try'"
station:"PERTHRadio"
timeplay:2020-07-17T10:39:00.000+00:00
__v:0
history:Array
0:"7320564F-76B2-40D0-A0E8-E3917148F567"
1:"7320564F-76B2-40D0-A0E8-E3917148F567"
}
Basically it's adding the same UUID twice in history.
I am using a findOneAndUpdate with $push.
The code I am using
const nowplayingData = {
"station": req.params.stationname,
"song": data[1],
"artist": data[0],
"timeplay":npdate
};
LNowPlaying.findOneAndUpdate(
nowplayingData,
{ $push: { history: [uuid] } },
{ upsert: true },
function(err) {
if (err) {
console.log('ERROR when submitting round');
console.log(err);
}
}
);
Usually when people experience an issue like this It's because the function / route the code is in is being run twice. (Again -usually- this is due to debugging where the debugger is firing an extra call or something of the sort).
Regardless if this happens to you while debugging or in production you can just start using $addToSet instead of push, this will guarantee duplicate values will not be pushed.
LNowPlaying.findOneAndUpdate(
nowplayingData,
{ $addToSet: { history: [uuid] } },
{ upsert: true },
function(err) {
if (err) {
console.log('ERROR when submitting round');
console.log(err);
}
}
);

Can Update document with mongodb query but not work when do in mongoose [duplicate]

This question already has answers here:
Update nested subdocuments in MongoDB with arrayFilters
(2 answers)
Closed 3 years ago.
My collection is like this: https://mongoplayground.net/p/91InBXrUq7R
With this query I can update replies.likes
db.getCollection("posts").updateOne(
{
"_id": ObjectId("5da832caeb173112348e509b"), //posts._id
"comments.replies._id":ObjectId("5db6a88f7c6cfb0d0c2b689b"),//replies._id
},
{ "$push": { "comments.$[outer].replies.$[inner].likes": "10000012" } },
{
"arrayFilters": [
{ "outer._id": ObjectId("5db06e11d0987d0aa2cd5593") },//comments._id
{ "inner._id": ObjectId("5db6a88f7c6cfb0d0c2b689b") }//replies._id
]
}
)
But when I code using mongoose, express, collection not update
//Like Reply toggle
router.post("/toggleLikeReply", function(req, res, next) {
var id_post = req.body.id_post;
var id_comment = req.body.id_comment;
var id_reply = req.body.id_reply;
var id_user = req.user._id;
console.log("id_post: "+id_post+" id_comment: "+id_comment+" id_reply: "+id_reply+" id_user: "+id_user);
//todo
Post.aggregate([
{ $match: {_id: ObjectId(id_post),"comments._id": ObjectId(id_comment)}},
{ $unwind: "$comments"},
{ $match: { "comments._id": ObjectId(id_comment)}},
{ $project: {"replies": "$comments.replies", _id: 0}},
{ $match: { "replies._id": ObjectId(id_reply)}},
{ $project: {"likes": "$replies.likes", _id: 0}},
]).exec((err, users_liked) => {
var index = users_liked[0].likes[0].indexOf(id_user);
console.log(users_liked[0].likes[0]);
//todo
if (index == -1) {
const updatePost = async () => {
try {
await Post.updateOne({
_id: ObjectId(req.body.id_post),
"comments.replies._id": ObjectId(req.body.id_reply)},
{ $push: {"comments.$[outer].replies.$[inner].likes": ObjectId(req.user._id)} },
{
"arrayFilters": [
{ "outer._id": ObjectId(req.body.id_comment) },
{ "inner._id": ObjectId(req.body.id_reply) }
]
}
);
} catch (error) {
console.log("error", error);
}
};
updatePost().then(function(data) {res.send({ like: true, success: true})});
}else{
const updatePost = async () => {
try {
await Post.updateOne({
_id: ObjectId(req.body.id_post),
"comments.replies._id": ObjectId(req.body.id_reply)},
{ $pull: {"comments.$[outer].replies.$[inner].likes": ObjectId(req.user._id)} },
{
"arrayFilters": [
{ "outer._id": ObjectId(req.body.id_comment) },
{ "inner._id": ObjectId(req.body.id_reply) }
]
}
);
} catch (error) {
console.log("💥", error);
}
};
updatePost().then(function(data) {res.send({ like: false, success: true})});
}
})
});
I logged the all the id is come and the same as I did with mongo query directly .
id_post: 5da832caeb173112348e509b
id_comment: 5db06e11d0987d0aa2cd5593
id_reply: 5db6a88f7c6cfb0d0c2b689b
id_user: 5da85558886aee13e4e7f044
What is wrong with my code using mongoose and express?
Try This Query
var mongoose = require('mongoose');
const Schema = mongoose.Schema
const ObjectId = Schema.Types.ObjectId
const updatePost = async () => {
try {
await Post.updateOne({
_id: ObjectId(req.body.id_post),
"comments.replies._id": ObjectId(req.body.id_reply)},
{ $push: {"comments.$[outer].replies.$[inner].likes": req.user._id} },
{
"arrayFilters": [
{ "outer._id": ObjectId(req.body.id_comment) },
{ "inner._id": ObjectId(req.body.id_reply) }
]
}
);
} catch (error) {
console.log("error", error);
}
};
updatePost().then(function(data) {res.send({ like: true, success: true})});

how to write findOneAndUpdate query in express.js?

i have shown my data , which is stored in database like this
{
"_id": {
"$oid": "5799995943d643600fabd6b7"
},
"Username": "xx",
"Email": "xx#gmail.com",
"Info": "Deactivate",
"Description": "aajdjdjddjdkjddjdjdhdj",
"VerificationCode": "594565",
"VerificationExpires": {
"$date": "2016-10-07T10:20:20.077Z"
}
}
My controller:
if Username, Email, Info are matched I need to update " Info = 'Active' " this is working at the same time i need to delete 'VerificationCode' field and 'VerificationExpires' field how can i achieve this?
exports.updatearticle = function(req, res) {
Article.findOneAndUpdate(
{ "Username":'xx', "Email":'xx#gmail.com', "Info": "Deactivate" },
{ "$set": { "Info": "Active" } },
{ "new": true }
function (err, doc) {
if (err) { // err: any errors that occurred
console.log(err);
} else { // doc: the document before updates are applied if `new: false`
console.log(doc); // , the document returned after updates if `new true`
console.log(doc.Info);
}
}
);
};
above condtion matched and info getting changed but i want to delete VerificationCode,VerificationExpires some one help me out
exports.updatearticle = function(req, res) {
Article.findOne( { "Username":'xx', "Email":'xx#gmail.com', "Info": "Deactivate" }, function(err, result){
if (!err && result) {
result.Info = "Active"; // update ur values goes here
result.VerificationCode = "";
result.VerificationExpires = {};
var article = new Article(result);
article.save(function(err, result2){
if(!err) {
res.send(result2);
} else res.send(err);
})
} else res.send(err);
});
}
home this may help

fail to update documents with cursor.forEach

This Meteor client code does not update the documents found as expected. The console.log(res) prints '0' when there are documents to be updated.
Why and how to fix it? Thanks
MyCollection.find({
class: 'check-filter'
}).forEach((obj) => {
MyCollecction.update({
obj
}, {
$set: {
class: ''
}
}, (err, res) => {
if (!err) {
console.log(res);
}
});
});
Change your selector to use the object's _id:
MyCollection.find({ class: 'check-filter' }).forEach(obj => {
MyCollection.update(obj._id, { $set: { class: '' }}, (err, res) => {
if (!err) {
console.log(res);
}
});
});
Also you have a typo where you're trying to do MyCollecction.update instead of MyCollection.update