how do i push a document on a nested mongodb - mongodb

if I want to add a review, with author,rating and reviewText to the first title, how do I do it.
{
"_id": ObjectId("58dd21c3cb77090b930b6063"),
"bookAuthor": "wwww",
"titles": [{
"title": "this is title",
"_id": ObjectId("58dd3f2701cc081056135dae"),
"reviews": [],
"favouredBy": [
"bb, aa, cc"
]
}, {
"title": "this is the second tittle",
"_id": ObjectId("58dd42a59f12f110d1756f08"),
"reviews": [],
"favouredBy": [
"all"
]
}],
"__v": 0
}
from with in the application this is what I tried but keep getting "TypeError: Cannot read property 'push' of undefined" error
module.exports.reviewsCreate = function(req, res) {
if (req.params.bookid) {
Bok
.findById(req.params.bookid)
.select('titles')
.exec(
function(err, book) {
if (err) {
sendJSONresponse(res, 400, err);
} else {
doAddReview(req, res, book);
}
}
);
} else {
sendJSONresponse(res, 404, {
"message": "Not found, bookid required"
});
}
};
var doAddReview = function(req, res, book, author) {
console.log(book);
if (!book) {
sendJSONresponse(res, 404, "bookid not found");
} else {
book.titles.reviews.push({
author: author,
rating: req.query.rating,
reviewText: req.query.reviewText
});
book.save(function(err, book) {
var thisReview;
if (err) {
sendJSONresponse(res, 400, err);
} else {
sendJSONresponse(res, 201, book);
}
});
}
};

Related

How to populate array of objects in mongoose

I have this code -
const getAllCourses = async (req, res) => {
const courses = await Course.find({});
try {
await courses.populate('professor')
res.send({ status: 200, data: { courses } });
} catch (err) {
res.status(500).send({ status: 500, message: "Internal server error." });
}
};
Also, this is the response I'm getting from postman -
{
"status": 200,
"data": {
"courses": [
{
"_id": "61dc47f58f88c1a7e9bd36b6",
"name": "Course1",
"professor": "61dc1299431cd669faad7d0f",
"students": [
{
"student": "61dc0b7f103b531f105e8e4c",
"_id": "61dc47f58f88c1a7e9bd36b7"
},
{
"student": "61dc220885886a9f1d8e94d0",
"_id": "61dc47f58f88c1a7e9bd36b8"
}
],
"createdAt": "2022-01-10T14:51:33.313Z",
"updatedAt": "2022-01-10T14:51:33.313Z",
"__v": 0
},
{
"_id": "61dc47fb8f88c1a7e9bd36bf",
"name": "Course2",
"professor": "61dc1299431cd669faad7d0f",
"students": [
{
"student": "61dc0b7f103b531f105e8e4c",
"_id": "61dc47fb8f88c1a7e9bd36c0"
},
{
"student": "61dc220885886a9f1d8e94d0",
"_id": "61dc47fb8f88c1a7e9bd36c1"
}
],
"createdAt": "2022-01-10T14:51:39.704Z",
"updatedAt": "2022-01-10T14:51:39.704Z",
"__v": 0
}
]
}
}
Now what I'm trying to do is to populate the professor and the students but it doesn't seem to work.
I tried populating "courses.professor", "course.professor", "professor" but nothing worked for me.
What am I missing?
Here is an example of how this can be done for a document with an array friends on it:
User.
findOne({ name: 'Val' }).
populate({
path: 'friends',
// Get friends of friends - populate the 'friends' array for every friend
populate: { path: 'friends' }
});
I just solved it by chaining the populate method directly after the Course.find({}) and it just worked, I'm not sure why though.
Solution:
const getAllCourses = async (req, res) => {
const courses = await Course.find({}).populate('professor').populate('students.student');
try {
res.send({ status: 200, data: { courses } });
} catch (err) {
res.status(500).send({ status: 500, message: err.message });
}
};

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

Update single specific field only when using $ in embedded document Mongodb

Here's my snippet of code.
router.post(
"/chapter/officers/edit/:id/:c_id",
async (req, res) => {
try {
const updateChapter = await Council.findOneAndUpdate(
{ "chapters._id": req.params.c_id },
{
"chapters.$.officers": req.body,
}
);
if (!updateChapter) return res.status(404).json({ msg: "Not found" });
res.json("Edit Success");
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
);
I am planning on updating only one specific field at a time BUT when I tried to send this JSON from Postman
{
"grandTriskelion": "sample"
}
The other filled in field values becomes an empty string. Heres an example of my res.json
"_id": "5fc9cbb7ba7e2e2430c9a4d8",
"name": "Maria Aurora",
"code": "MA",
"chapters": [
{
"officers": {
"grandTriskelion": "sample",
"deputyGrandTriskelion": "",
"masterWilderOfTheWhip": ""
},
"_id": "5fca014e49fa3f2910794bb8",
"name": "Maria Aurora Community Based"
}
],
I've hit a roadblock. I'm a beginner at MERN stack.

"Cannot read property 'apply' of undefined"? in loopback 3

i don't know why i have this error
when i executing the method in the loopback explorer gives the error
This is the .js file used in the project
'use strict';
module.exports = function(Puntoventa) {
var app = require('../../server/server');
Puntoventa.getAll = function() {
Puntoventa.find({ where: { nombre: !null } }, function(err, punto) {
if (err) return callback(err);
return punto;
});
}
}
and this is the model .json
"name": "puntoVenta",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"acls": [],
"methods": {
"getAll": {
"accepts": [],
"returns": [{
"arg": "punto",
"type": "object",
"root": true,
}],
"http": [{
"path": "/getAll",
"verb": "get"
}]
}
}
The error is due to a bug in sql query, you cannot use !null instead you can use neq given by loopback
Puntoventa.find({ where: { nombre: { "neq": null} } }, function(err, punto) {
if (err) return callback(err);
return punto;
});
Please use { "neq": null} } and define callback in getAll().
Puntoventa.getAll = function(callback) {
Puntoventa.find({ where: { nombre: { "neq": null} } } }, function(err, punto) {
if (err) return callback(err);
return callback(null,punto);
});
}

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