how to pass fieldname dynamically in mogodb - node.js

I want to pass field name dynamically in Mondgodb while query the collection. e.g.
emp.ply = function(res,res) {
Employee.find({area: 'Plymouth'}).exec(function(err,PLY) {
res.render("../index", {resultset: PLY})
here I'm doing query on field name area which is hard code. Instead of i want to pass fieldname dynamically. How we can achieve it in nodeJS

So, conceptually you just need to build the query object before sending it to the .find() function. Perhaps something like this:
const query = {}
const fieldname = 'area'
const fieldvalue = 'Plymouth'
query[fieldname] = fieldvalue
Employee.find(query).exec((err, ply) => {
// do whatever
});
You could conceptually extract both fieldname and fielvalue from req.body or req.query depending on what you're doing.

If your code supports ES6 or (any latest browser except IE), we can do this:
emp.ply = function(res,res) {
let searchField = 'area'; // this can be anything dynamically
Employee.find({[searchField]: 'Plymouth'}).exec(function(err,PLY) {
res.render("../index", {resultset: PLY})
})
}
You can refer to MDN docs about Computed property names

Related

Can't use variables as key, value for mongoose .find()

I'm using mongoose 5.11.4 and trying to find documents. On the official docs they say
MyModel.find({ name: /john/i })
I wanna know how to use variables for "name" & "john" and get the exact thing done. this is an API that I'm working on. filter (name) and the value (john) gonna decide by the frontend user. We should search for a given field using the value. Any suggestions?
let filter = req.params.filter
let value = req.params.value
MyModel.find({ filter : /value/i })
doesn't work
You can use the RegExp object to convert the value to a regular expression.
let regex = new RegExp(`${value}`,'options');
Now you can use it on mongoose query.
model.find({name:regex});
this worked : )
let filter = req.params.filter
let value = req.params.value
const filterParam = {}
filterParam[filter] = { $regex: .*${value}.* }
const suppliers = await Supplier.find(filterParam)

Mongoose, NodeJS & Express: Sorting by column given by api call

I'm currently writing a small API for a cooking app. I have a Recipe model and would like to implement sorting by columns based on the req Parameter given.
I'd like to sort by whatever is passed in the api call. the select parameter works perfectly fine, I can select the columns to be displayed but when I try to sort anything (let's say by rating) the return does sort but I'm not sure what it does sort by.
The code i'm using:
query = Recipe.find(JSON.parse(queryStr));
if(req.query.select){
const fields = req.query.select.split(',').join(' ');
query = query.select(fields);
}
if(req.query.sort){
const sortBy = req.query.sort.split(',').join(' ');
query = query.sort({ sortBy: 1 });
} else {
query = query.sort({ _id: -1 });
}
The result, when no sorting is set: https://pastebin.com/rPLv8n5s
vs. the result when I pass &sort=rating: https://pastebin.com/7eYwAvQf
also, when sorting my name the result is also mixed up.
You are not using the value of sortBy but the string "sortBy". You will need to create an object that has the rating as an object key.
You need the sorting object to look like this.
{
rating: 1
}
You can use something like this so it will be dynamic.
if(req.query.sort){
const sortByKey = req.query.sort.split(',').join(' ');
const sortByObj = {};
sortByObj[sortByKey] = 1; // <-- using sortBy as the key
query = query.sort(sortByObj);
} else {
query = query.sort({ _id: -1 });
}

NodeJS/Mongoose - How to reference individual models after concatenation?

I am concatenating two models (Blogs and Events) so I can display all records from both collections in a single forEach loop:
const blogs = await Blog.find({});
const events = await Event.find({});
const blogsAndEvents = blogs.concat(events);
blogsAndEvents.forEach(function(blogOrEvent) { etc. etc.
However, within the forEach loop, in some cases, I want to still reference the original model it comes from, e.g. 'if Blog, title equals BLOG, if Event, title equals event). I have a workaround for this where I am using a unique field from each model to determine the underlying model, like this:
if (blogOrEvent.blogPost) {
title = "BLOG"
} elseIf (blogOrEvent.eventDate) {
title = "EVENT"
}
This approach doesn't seem very clean to me though as it relies on their being a unique field in each model. It there a better way I can access the original underlying model within the loop? Thanks.
With mongoose documents it can be distinctly verified which Model they belong to using instance of :
const blogs = await Blog.find({});
const events = await Event.find({});
const blogsAndEvents = blogs.concat(events);
blogsAndEvents.forEach(function (blogOrEvent) {
if (blogOrEvent instanceof Blog) {
title = "BLOG";
} else if (blogOrEvent instanceof Event) {
title = "EVENT";
}
});

Stringifying JSON data loses object I'm trying to stringify

I'm new to NodeJS and I'm trying to learn it a bit better by writing a Discord bot. But I'm having an issue with stringifying an object to JSON. I think it's having an issue with the array I'm setting, but I'm not sure how else I would do this. If I'm not supposed to set an array and using my guildMembers example below, how else should I insert this data into my JSON file?
I've looked through a few examples here on StackOverflow and found this particular article: JSON Stringify Removing Data From Object. However, it's not clear to me given what I'm trying to achieve.
var o = {};
var guildKey = guild.id;
o[guildKey] = [];
o[guildKey]['guildMembers'] = {};
var guildMembers = []
guild.members.forEach(function(guildMember, guildMemberId) {
if (!guildMember.user.bot){
var memberData = {
id: guildMember.id,
data: {
userName: guildMember.user.username,
nickName: guildMember.nickname,
displayName: guildMember.displayName,
joinedAt: guildMember.joinedAt
}
}
guildMembers.push(memberData);
};
});
o[guildKey]['guildMembers'] = guildMembers;
json = JSON.stringify(o);
I am expecting the data to show the guildMembers object with the array under the guildKey object. However, the JSON shows only the guildKey object with an empty array:
{"guildKey":[]}
You make guildKey an array and then try to use it as an object ...
Solution is:
o[guildKey] = {};
Just like in the mentioned post.
It is because you are assigning a key-value pair to an array with
o[guildKey]['guildMembers'] = { }; <= o[guildKey]
When iterating over an array to display the contents, JavaScript does not access non-integer keys. You should store o[guildKey] as an object instead.

Cloud Functions & Firestore: Iterate over document.data

The database structure looks like this:
User {id}
Settings (Collection)
device_uids(document)
{device_uid_1}: Boolean
(...)
{device_uid_n}: Boolean
I want to get the document and access all of the device_uids within that document.
I tried like this, however the console logs, that forEach is not definded:
const settings_ref = admin.firestore().collection('User').doc(uid).collection('Settings').doc('device_uids');
settings_ref.get()
.then(snap =>{
let uids = snap.data();
uids.array.forEach(element => {
let device = element.key;
if(device != device_uid){
//GO ON
}
});
})
How can I access the values individually?
You don't have a field called array in your document, so uids.array will always be undefined. If you just want to iterate all the properties of the document, it's just like iterating all the properties of a plain old JavaScript object:
const data = snap.data();
for (const key in data) {
const value = data[key];
// now key and value are the property name and value
}

Resources