I want to make it so that can choose by what value to sort.
Can't pass the parameter this way:
order: {
sort: order
},
How do I do this?
const search = query.search || '';
const order = query.order || 'ASC';
const sort = query.sort || '';
const [data, total] = await this.userRepository.findAndCount({
relations: ['role'],
where: [{
username: ILike(`%${search}%`),
email: ILike(`%${search}%`)
}],
order: {
sort: order
},
take,
skip: (page - 1) * take
});
What you're looking for is this:
const [data, total] = await this.userRepository.findAndCount({
...
order: {
[sort]: order
},
...
});
Although, I should warn you that this might throw you an exception when you have an empty string for sort.
Related
i'm trying to loop over an array of objects, saving them to MongoDB and then add the returned ObjectIds to a parent Schema which then is also saved. I'm at a loss here.
Everything gets saved correctly but the Recipe (parent) apparently is saved before I get the returned ObjectIds of the Tags (children). I feel like I've used the async and await keywords a bit to often.
Can someone help? Code simplified, but I can post more if needed.
Parent Schema:
const recipe = new mongoose.Schema(
{
name: String,
ingredients: [
{
type: mongoose.SchemaTypes.ObjectId,
ref: "Ingredient",
},
],
}
);
Child Schema:
const ingredientSchema = new mongoose.Schema({
value: String,
label: String,
});
Payload:
{
name: "Rezept",
ingredients: [
{
label: "zutat",
value: "Zutat",
},
{
label: "schokolade",
value: "Schokolade",
},
],
};
My router:
recipesRouter.post("/", async (req, res) => {
const { body } = req;
const saveIngredients = async () => {
let ingredientIDs = [];
body.ingredients.map(async (ingredient) => {
const i = new Ingredient({
value: ingredient.value,
label: ingredient.label,
});
const savedIngredient = await i.save();
ingredientIDs.push(savedIngredient._id);
});
return ingredientIDs;
};
const recipe = new Recipe({
name: body.name,
ingredients: (await saveIngredients()) || [],
});
const savedRecipe = await recipe.save();
res.status(201).json(savedRecipe);
});
Returned recipe:
savedRecipe: {
name: 'asd',
ingredients: [],
_id: new ObjectId("62782b45a431e6efb7b8b1a7"),
}
As I said, both ingredients individually and the recipe is saved to the MongoDB after this but not the ingredient IDs in the recipe. The returned recipe has an empty array in ingredients. I guess the recipe is saved too soon before MongoDB can return ObjectIds for the ingredients.
Thanks for any help.
First of all, your post method is an async, so everything inside it is wrapped in a resolved promise automatically.
Do you really need to make your saveIngredients as an async? IMHO, it's better to let the saveIngredients not be in another async.
And then we can remove the empty list, and just wait for the saveIngredients() finish first.
const recipe = new Recipe({
name: body.name,
ingredients: await saveIngredients(),
});
Your guess is correct, the Recipe was saved first because all the conditions are fulfilled because it doesn't need to wait for the saveIngredients since you provided a [] as the default value. And your saveIngredients is run in parallel.
I got it smh. Turns out async in a .map or .foreach doesn't go well. I turned it into a simple for loop. It's still bloated/lot of steps imo but it works!
recipesRouter.post("/", async (req, res) => {
const { body } = req;
const saveIngredients = async () => {
let ingredientIDs = [];
for (let i = 0; i < body.ingredients.length; i++) {
const el = body.ingredients[i];
const ing = new Ingredient({
value: el.value,
label: el.label,
});
const savedIngredient = await ing.save();
ingredientIDs.push(savedIngredient._id);
}
return ingredientIDs;
};
const ingredientIDs = await saveIngredients();
const recipe = new Recipe({
name: body.name,
ingredients: ingredientIDs,
});
const savedRecipe = await recipe.save();
res.status(201).json(savedRecipe);
});
I want to decrease previours quantity by 1 how can I do this in Node Js Mongo Db
Here is my code:
app.put('/quantityUpdate',async(req,res)=>{
const id = req?.body?.id;
const dec= req?.body?.dec;
const filter = {_id:ObjectId(id)}
// this option instructs the method to create a document if no documents match the filter
const options = { upsert: true };
const updateDoc = {
$set: {
quantity: //I'm stuck in this place
},
};
const result = await products.updateOne(filter, updateDoc, options);
return res.send(result);
})
Instead of $set use $inc. It increments a field by a specified value.
To decrease the value by 1 you change your code to:
const updateDoc = { $inc: { quantity: -1 } }
To get more details, checkout the documentation.
I'm writing below content to JSON file, I would like to ignore the fields which has value null or blank - in this case I want to ignore productPrice and productRating fields while writing to JSON file, I'm not much familiar with NodeJS - can someone please help how can I achieve this in NodeJS?
Please find my code below:
const fs = require('fs');
const params = {
productID: 'prd323434',
productName: 'Google',
productDesc: 'Larum ipsum',
productPrice: null,
productRating: '',
productReview: 'Lorum ipsum'
};
var data = {
productID: params.productID,
productName: params.productName,
productDesc: params.productDesc,
productPrice: params.productPrice,
productRating: params.productRating,
productReview: params.productReview
};
let jsonContent = JSON.stringify(data);
fs.writeFileSync('test.json', jsonContent);
console.log(jsonContent)
You look like you are just filtering your object for "falsy" values.
So take params, use Object.entries on it to get something like this:
[
[productID, 'prd323434'],
[productName, 'Google'],
...
]
Use the filter method on the result, destructure each param with ([k,v]). Then only return it if v is "truthy".
const data = Object.fromEntries(Object.entries(params).filter(([k,v]) => v))
Or perhaps in a more readable way:
const entries = Object.entries(params)
const filtered = entries.filter(([k,v]) => {
if (v === null || v === "") {
return false
} else {
return true
}
}))
const data = Object.fromEntries(filtered)
I am trying to sort orders in descending and start after on particular key but its not working
nextAfter : -Mk4-n5BnVpwhum62n2g or any Key / _id
db record:
{
'-Mk4-n5BnVpwhum62n2g': {
_id: '-Mk4-n5BnVpwhum62n2g',
createdAt: -1632171667626,
name: 'abc'
},
'-Mk40Ko9DbSeMdjIpY4': {
_id: '-Mk40Ko9DbSeMdjIpY4',
createdAt: -1632171809831,
name: 'new '
}
}
trying query :
query = dbRef.orderByChild('createdAt').startAfter(nextAfter).limitToFirst(limit);
The startAfter() method accepts two parameters - the first is the relevant orderBy value and the second is the optional key of the last entry (for when multiple entries have the same value for the orderBy criteria). So to correctly paginate the reference, you need to pass the previous entry's createdAt value and its key.
const baseQuery = dbRef
.orderByChild('createdAt')
.limitToFirst(limit);
let pageCount = 0, lastChildOnPage = undefined;
const children = [];
while (true) {
const pageQuery = pageCount === 0
? baseQuery
: baseQuery
.startAfter(lastChildOnPage.createdAt, lastChildOnPage.key);
const pageSnapshot = await pageQuery.once('value');
pageSnapshot.forEach((childSnapshot) => {
children.push({ key: childSnapshot.key, ...childSnapshot.val() });
})
const newLastChildOnPage = children[children.length-1];
if (lastChildOnPage !== newLastChildOnPage) {
lastChildOnPage = newLastChildOnPage;
pageCount++;
} else {
break; // no more data
}
}
console.log(`Grabbed ${pageCount} page(s) of data, retrieving ${children.length} children`);
I'm searching the web and can't find the right way to make a query in my MongoDB using Mongoose.
I want to perform a query if I receive the parameter:
async list(req, res) {
const { page = 1, limit = 10, status = "" } = req.query;
const orders = await Order.paginate(
{ status },
{
page: parseInt(page),
limit: parseInt(limit),
populate: { path: "user", select: "firstName lastName" }
}
);
return res.send(orders);
}
So for example, if status is not provided in the URL, I want to return all documents, and if I provide the status, return only the ones that match.
I can achieve what I'm looking for if I pass a status, but I can't return all documents if I don't pass a status. I tried with "", undefined and null, but none of them worked.
I also think the way I'm approaching it is not the best, because I'll have to declare in const { page = 1, limit = 10, status = "" } = req.query; all possible query parameters.
How should I handle it?
PS: I'm using mongoose-paginate, but they redirect the query documentation to the MongoDB documentation, so I assume it's the same.
Thanks in advance!
Simple solution. I could accomplish it using the spread operation of ES6:
async list(req, res) {
const { page = 1, limit = 10 } = req.query;
let filters = req.query;
filters = { ...filters, page: undefined, limit: undefined };
const orders = await Order.paginate(
{ ...filters },
{
page: parseInt(page),
limit: parseInt(limit),
populate: { path: "user", select: "firstName lastName" }
}
);
return res.send(orders);
}
This ensures that undefined objects won't make part of the query