how to remove _id from create replay mongodb node js - node.js

exports.createDD_PR_addresstype = asyncHandler(async (req, res, next) => {
const dropdowns = await DD_PR_addresstype.create(req.body);
res.status(200).json({
success: true,
data: dropdowns
});
});
replay
{
"success": true,
"data": {
"_id": "5f252a444824ac0164195c1a",
"label": "Battery",
"company_id": "5f17e0f4d6eded0db090b272",
"value": 1,
"__v": 0
}
}
i want to show only label and value. is there is any pre functions available to select created replay or i have to use seperate find query

You could destructure the query response:
const { label, value } = await DD_PR_addresstype.create(req.body);
res.status(200).json({
success: true,
data: { label, value }
});
But that's just a way to write less code for:
data: {
value: dropdowns.value,
label: dropdowns.label
}
If you're looking for retrieving the document later with only the given props then the projection answer (which was deleted in between) is the way to go.
Since the other projection answer was deleted I add it here (using _id just as example):
const dropdowns = await DD_PR_addresstype.find( { _id: "5f252a444824ac0164195c1a" }, { label: 1, value: 1 } )

Related

mongoose query multiple operations in one request

I'm trying to use the $set, $addToSet and $inc at the same time for my report of sales and
tbh I'm not even sure if I did the right approach since it's not working.
once I send the request, the console gives me the error 404 but when I check the req.body the data was correct. so I was wondering if the problem is my query on mongoose because this was the first time I use multiple operations on mongoose query
export const report_of_sales = async (req, res) => {
const { id } = req.params;
console.log(req.body);
try {
if (!mongoose.Types.ObjectId.isValid(id)) return res.status(404).json({ message: 'Invalid ID' });
let i;
for (i = 0; i < req.body.sales_report.length; i++) {
await OwnerModels.findByIdAndUpdate(id, {
$inc: {
total_clients: req.body.total_clients,
total_product_sold: req.body.sales_report[i].qty,
sales_revenue: req.body.sales_report[i].amount
},
$set: {
"months.$[s].month_digit": req.body.months[i].month_digit,
"months.$[s].targetsales": req.body.months[i].targetsales,
"months.$[s].sales": req.body.months[i].sales,
},
$addToSet: {
sales_report: {
$each: [{
identifier: req.body.sales_report[i].identifier,
product_name: req.body.sales_report[i].product_name,
generic_name: req.body.sales_report[i].generic_name,
description: req.body.sales_report[i].description,
qty: req.body.sales_report[i].qty,
amount: req.body.sales_report[i].amount,
profit: req.body.sales_report[i].profit
}]
}
}
}, {
arrayFilters: [
{
"s.month_digit": req.body.months[i].month_digit
}
],
returnDocument: 'after',
safe: true,
}, { new: true, upsert: true })
}
} catch (error) {
res.status(404).json(error);
}
}
Well, you are looking at the body, but you are actually using query parameter named id. This is probably undefined, which leads to ObjectId.isValid(id) returning false.
You should decide on whether to pass this data as a query param or in the request body and adjust your code accordingly.

How can I find specific document and update a value of specific key inside array?

I have a structure like this:
{
_id: new ObjectId("634aa49f98e3a05346dd2327"),
filmName: 'Film number 1',
episodes: [
{
episodeName: 'Testing 1',
slugEpisode: 'testing-1',
_id: new ObjectId("6351395c17f08335f1dabfc9")
},
{
episodeName: 'Testing 2',
slugEpisode: 'testing-2',
_id: new ObjectId("6351399d9a2533b9be1cbab0")
},
],
},
{
_id: new ObjectId("634aa4cc98e3a05346dd232a"),
filmName: 'Film number 2',
episodes: [
{
episodeName: 'Something 1',
slugEpisode: 'something-1',
_id: new ObjectId("6367cce66d6b85442f850b3a")
},
{
episodeName: 'Something 2',
slugEpisode: 'something-2',
_id: new ObjectId("6367cd0e6d6b85442f850b3e")
},
],
}
I received 3 fields:
_id: Film _id
episodeId: Episode _id
episodeName: The content I wish to update
I tried to find a specific Film ID to get a specific film, and from then on, I pass an Episode ID to find the exact episode in the episodes array. Then, update the episodeName of that specific episode.
Here's my code in NodeJS:
editEpisode: async (req, res) => {
const { _id } = req.params
const { episodeId, episodeName } = req.body
try {
const specificResult = await Films.findOneAndUpdate(
{ _id, 'episodes._id': episodeId },
{ episodeName }
)
console.log(specificResult)
res.json({ msg: "Success update episode name" })
} catch (err) {
return res.status(500).json({ msg: err.message })
}
},
But what console.log display to me is a whole document, and when I check in MongoDB, there was no update at all, does my way of using findOneAndUpdate incorrect?
I'm reading this document: MongooseJS - Find One and Update, they said this one gives me the option to filter and update.
The MongoDB server needs to know which array element to update. If there is just one array element to update, here's one way you could do it. (I picked a specific element. You would use your req.params and req.body.)
db.films.update({
"_id": ObjectId("634aa4cc98e3a05346dd232a"),
"episodes._id": ObjectId("6367cd0e6d6b85442f850b3e")
},
{
"$set": {
"episodes.$.episodeName": "Something Two"
}
})
Try it on mongoplayground.net.
You can use the filtered positional operator $[<identifier>] which essentially finds the element or object (in your case) with a filter condition and updates that.
Query:
const { _id } = req.params
const { episodeId, episodeName } = req.body
await Films.update({
"_id": _id
},
{
$set: {
"episodes.$[elem].episodeName": episodeName
}
},
{
arrayFilters: [
{
"elem._id": episodeId
}
]
})
Check it out here for example purpose I've put ids as numbers and episode name to update as "UpdatedValue"

Firebase database collection returns empty array when trying to get all documents

I'm trying to get all documents from my database collection "posts" but I'm getting an empty array instead.
The strange thing is that I'm able to get all documents from another collection called "users" that has the same structure and using the exact same code.
I've spent days looking for an answer but I haven't been able to find the solution.
This is the request:
const db = admin.firestore();
exports.getAllPosts = (req, res) => {
db.collection('posts')
.orderBy('createdAt', 'desc')
.get()
.then(snapshot => {
let posts = [];
snapshot.forEach((doc) => {
posts.push({
id: doc.id,
body: doc.data().body,
author: doc.data().author,
createdAt: doc.data().timestamp,
voteScore: doc.data().voteScore
});
});
return res.json(posts);
})
.catch(err => {
console.error(err);
res.status(500).json({ error: err.code });
});
}
And this is the response:
[]
This is what my current collection looks like:
Posts collection screenshot
This the response that I get when I return "snapshot":
{
"_query": {
"_firestore": {
"_settings": {
"projectId": "readable-bf7a6",
"firebaseVersion": "9.6.0",
"libName": "gccl",
"libVersion": "4.10.0 fire/9.6.0"
},
"_settingsFrozen": true,
"_serializer": {
"allowUndefined": false
},
"_projectId": "readable-bf7a6",
"registeredListenersCount": 0,
"bulkWritersCount": 0,
"_backoffSettings": {
"initialDelayMs": 100,
"maxDelayMs": 60000,
"backoffFactor": 1.3
},
"_clientPool": {
"concurrentOperationLimit": 100,
"maxIdleClients": 1,
"activeClients": {},
"failedClients": {},
"terminated": false,
"terminateDeferred": {
"promise": {}
}
}
},
"_queryOptions": {
"parentPath": {
"segments": []
},
"collectionId": "posts",
"converter": {},
"allDescendants": false,
"fieldFilters": [],
"fieldOrders": [
{
"field": {
"segments": [
"createdAt"
]
},
"direction": "DESCENDING"
}
],
"kindless": false
},
"_serializer": {
"allowUndefined": false
},
"_allowUndefined": false
},
"_readTime": {
"_seconds": 1622395245,
"_nanoseconds": 513743000
},
"_size": 0,
"_materializedDocs": null,
"_materializedChanges": null
}
Notice how the request for the collection "users" works successfully:
const db = admin.firestore();
exports.getAllUsers = (req, res) => {
db.collection('users')
.orderBy('createdAt', 'desc')
.get()
.then(snapshot => {
let users = [];
snapshot.forEach((doc) => {
let users = [];
snapshot.forEach((doc) => {
users.push({
id: doc.data().userId,
email: doc.data().email,
handle: doc.data().handle
});
});
return res.json(users);
})
.catch(err => {
console.error(err);
res.status(500).json({ error: err.code });
});
}
And the response:
[
{
"id": "EPoHBxhQFUXbcL3TCVx1LdUG2nO2",
"email": "ruben#gmail.com"
},
{
"id": "RqEa3dEq8TSDcZYeolXafju67rB2",
"email": "user10#gmail.com"
},
{
"id": "dxveb4n2iMQej5Q14uprsKRxFp23",
"email": "user4#gmail.com",
"handle": "user4"
},
{
"id": "YQPzBPcsqlVZk9iJEuZTHKUNuVG2",
"email": "user2#gmail.com",
"handle": "user2"
},
{
"id": "CZ05BJxi3TUOpIrmBaz539OWlbC3",
"email": "user#gmail.com",
"handle": "user"
},
{
"id": "t0t83BVwt4gVgJkDv7HL1r1MaKr1",
"email": "userJose2#gmail.com",
"handle": "Jose"
}
]
This is what the users collection looks like in Firebase:
Users collection screenshot
Why is one collection failing when the other works fine and I'm using the same code? What am I missing here?
Thanks in advance and I hope I've made it as clear as possible. Please let me know if you need me to provide anything else.
Very simple my friend, your posts documents can't be ordered like this:
.orderBy('createdAt', 'desc')
Because the post documents does not have the createdAt property, but they have a timestamp property, you should use that property to order your posts like this:
.orderBy('timestamp', 'desc')
I hope that helps 👍
I am not answering directly to #Ruben Garcia Bri, but for future firebase developers who may run into the problem of getting empty documents, I also ran into the same problem, but I solved it by adding a field to the particular document I am trying to retrieve.
Sometimes the cause is because the documents you are trying to get have no field in them.
I mean that a document must have a field before the server can recognize it as an existing document.
So if you run into this problem, consider adding a field to that document before you can successfully retrieve it.

Cannot find id and update and increment sub-document - returns null Mongoose/mongoDB

I have a problem where I cannot seem to retrieve the _id of my nested objects in my array. Specifically the foods part of my object array. I want to find the _id, of lets say risotto, and then increment the orders count dynamically (from that same object).
I'm trying to get this done dynamically as I have tried the Risotto id in the req.body._id and thats fine but i can't go forward and try to increment orders as i get null.
I keep getting null for some reason and I think its a nested document but im not sure. heres my route file and schema too.
router.patch("/update", [auth], async (req, res) => {
const orderPlus = await MenuSchema.findByIdAndUpdate({ _id: '5e3b75f2a3d43821a0fb57f0' }, { $inc: { "food.0.orders": 1 }}, {new: true} );
//want to increment orders dynamically once id is found
//not sure how as its in its own seperate index in an array object
try {
res.status(200).send(orderPlus);
} catch (err) {
res.status(500).send(err);
}
});
Schema:
const FoodSchema = new Schema({
foodname: String,
orders: Number,
});
const MenuSchema = new Schema({
menuname: String,
menu_register: Number,
foods: [FoodSchema]
});
Heres the returned Database JSON
{
"_id": "5e3b75f2a3d43821a0fb57ee",
"menuname": "main course",
"menu_register": 49,
"foods": [
{
"_id": "5e3b75f2a3d43821a0fb57f0",
"foodname": "Risotto",
"orders": 37
},
{
"_id": "5e3b75f2a3d43821a0fb57ef",
"foodname": "Tiramisu",
"orders": 11
}
],
"__v": 0
}
the id for the menuname works in its place but i dont need that as i need to access the foods subdocs. thanks in advance.
You are sending food id (5e3b75f2a3d43821a0fb57f0) to the MenuSchema.findByIdAndUpdate update query. It should be the menu id which is 5e3b75f2a3d43821a0fb57ee
You can find a menu by it's id, and update it's one of the foods by using food _id or foodname using mongodb $ positional operator.
Update by giving menu id and food id:
router.patch("/update", [auth], async (req, res) => {
try {
const orderPlus = await MenuSchema.findByIdAndUpdate(
"5e3b75f2a3d43821a0fb57ee",
{ $inc: { "foods.$[inner].orders": 1 } },
{ arrayFilters: [{ "inner._id": "5e3b75f2a3d43821a0fb57f0" }], new: true }
);
res.status(200).send(orderPlus);
} catch (err) {
res.status(500).send(err);
}
});
Update by giving menu id and foodname:
router.patch("/update", [auth], async (req, res) => {
try {
const orderPlus = await MenuSchema.findByIdAndUpdate(
"5e3b75f2a3d43821a0fb57ee",
{ $inc: { "foods.$[inner].orders": 1 } },
{ arrayFilters: [{ "inner.foodname": "Risotto" }], new: true }
);
res.status(200).send(orderPlus);
} catch (err) {
res.status(500).send(err);
}
});

mongoDb database form-data empty response

I am sending Rest POST Request(form-data) using postman to mongoDb. Even after providing all the key-value pairs in the Model, only the product _id gets stored into the database not other array of objects. Here's my model schema:
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
name: String,
price: Number,
editor1: String,
year: String,
quantity: Number,
subject: String,
newProduct: String,
relatedProduct: String,
//coverImage: { type: String, required: false }
});
module.exports = mongoose.model('Product', productSchema);
And here's my POST request for the products:
exports.products_create_product = (req, res, next) => {
const product = new Product(req.body);
product
.save()
.then(result => {
console.log(result);
res.status(201).json({
message: "Created product successfully",
createdProduct: {
name: result.name,
price: result.price,
_id: result._id,
request: {
type: "GET",
url: "http://localhost:3000/products/" + result._id
}
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
};
And this is my result output:
{
"message": "Created product successfully",
"createdProduct": {
"_id": "5b2df3420e8b7d1150f6f7f6",
"request": {
"type": "GET",
"url": "http://localhost:3000/products/5b2df3420e8b7d1150f6f7f6"
}
}
}
Tried every possible way to solve this but in vain.
try the callback
product.save((err,result) =>{
if(err){
res.status(500).json({
error: err
});
return false
}
res.status(201).json({
message: "Created product successfully",
createdProduct: {
name: result.name,
price: result.price,
_id: result._id,
request: {
type: "GET",
url: "http://localhost:3000/products/" + result._id
}
}
})
First let's try to understand why this happens ? ,
When you use .json() method inside this method it uses JSON.stringify() function what this function does is that take any JavaScript value and convert it to JSON string for example
let product = {
name : 'p1' ,
price : 200
}
console.log(JSON.stringify(product)); // {"name":"p1","price":200}
that's good , but you should know that if this function during the conversion see any undefined values it will be omitted ,
for example
let product = {
id:"23213214214214"
} // product doesn't have name property and its undefind
console.log(JSON.stringify({
id:product.id ,
name : product.name
})); // {"id":"23213214214214"}
if you look at the example above you'll see that because the value of name is **undefined ** you get a JSON output but only with the id value , and any value that is undefined will not be in the result .
that's the main reason why you get the result with only the product._id because other values like price and name are undefined .
so what to do to solve this problem ?
log the req.body and make sure that it has properties like name and price and I think this is the main reason of the problem because when you create the product variable it will only has the _id prop because other props are not exist .
after you create the product log it to the console and make sure that it has other properties like name and price
#mostafa yes I did tried.
{
"count": 3,
"products": [
{
"_id": "5b2e2d0cb70f5f0020e72cb6",
"request": {
"type": "GET",
"url": "https://aa-backend.herokuapp.com/products/5b2e2d0cb70f5f0020e72cb6"
}
},
{
"_id": "5b2e2d37b70f5f0020e72cb7",
"request": {
"type": "GET",
"url": "https://aa-backend.herokuapp.com/products/5b2e2d37b70f5f0020e72cb7"
}
},
{
this is the only output I am getting.

Resources