using mongoDB find() in express js - node.js

I was trying to check if a person had already applied for a job, so for that I used find() method to get the documents with the job Id and user ID I'm passing in, but it's always posting the data, not checking if those already exist?
here is the code,
router.post('/', async(req,res)=>{
const count = Apply.find({user:req.body.user, job:req.body.job}).count()
if(count>0){
return res.status(400).send('already applied')
}
else{
let apply = new Apply({
job :req.body.job,
user :req.body.user
})
apply = await apply.save();
if(!apply)
return res.status(400).send('cannot apply')
res.send(apply);
}
})
each request is getting ,
POST /api/v1/applys/ 200 141 - 58.007 ms
I dont have much idea about using find(), so can't figure out the problem here.

since you're using async/await add await before Apply.find
const count = await Apply.find({user:req.body.user, job:req.body.job}).count()

Related

What is the best way to use req.query to target all posts associated with a user through ObjectId-mongoose and node

How best can I target all posts associated with a user using the user's objectId? I am using mongoose and node.js.
I currently have this code:
router.get("/", async(req, res) => {
const username = req.query.user; // req.query is inbuilt. The last word .user is the keyword that will be used to query your logic
const catName = req.query.cat;
try {
let posts;
if(username) {
posts = await Post.find({username: username})
}
else if(catName) {
posts = await Post.find({categories:{
$in:[catName]
}})
}
else {
posts = await Post.find()
}
res.status(200).json(posts)
} catch(err) {
res.status(500).json(err)
}
})
It's not working for me. I want to get all the posts made by a user once you click on the user's name. username won't work for me because I used .populate() method from mongoose to ref username to my User Model from Post Model. So, username is now an objectId.
How do I query this using their objectId?
For anyone who may experience this challenge, especially those of us still learning. How I solved my problem:
Since username is now a referenced objectId due to use of .populate() method, I was using the username in postman like this localhost:5000/api/posts?user/dave
'dave' is the username of the user. This didn't work because mongoose was waiting for the objectId to fetch the user. So, after hours of search, it came to my mind to use the objectId instead of the username and it worked. I was able to fetch only the posts made by that objectId.
I had to do same thing in my React.js. My react route query looks like this:
<Link to={`/?user=${singleItem.username._id}`} className="link">
Everything is working fine, now.

Mongoose schema method returning is not a function

userSchema.method.comparePassword = async function(enteredPassword){
return await bcrypt.compare(enteredPassword, this.password);
}
So in the above code I have a mongoose User schema method in for my users database for comparing the encrypted passwords stored in my database each time a user tries to login.
const ispasswordMatched = await User.comparePassword(password);
In this code is where I call this method in the controler but each time I make a request with postman, it returns an error saying User.comparePassword is not a function. I've searched for a while about others experiencing this but nothing could solve my problem and it left me baffled on how to proceed about solving this. Any advice or tips is greatly apriciated.
Quick edit I am using mongodb version 4.4 with mongoose version 5.12.5
I think this is a typo, you're missing the "s" after method. Try this:
userSchema.methods.comparePassword = async function(enteredPassword){
return await bcrypt.compare(enteredPassword, this.password);
}
Mongoose document here
I know this is already answered but I had the same problem and it fixed by using findOne() instead of find().
i would prefer to use it like the referred method in the mongoose docs
https://mongoosejs.com/docs/api.html#schema_Schema-method
where mentioning the name is an argument for the method function.Not like what you have done here
eg.
const schema = kittySchema = new Schema(..);
schema.method('meow', function () {
console.log('meeeeeoooooooooooow');
})
const Kitty = mongoose.model('Kitty', schema);
const fizz = new Kitty;
fizz.meow();
I faced similar error in my code.. later on I realised that that my custom static schema method returns an array even when there is only a single document... the following code worked.
const user = await User.findByName("Meghna")
//user.sayHi() -> this one was failing with not a function error
user[0].sayHi()
console.log(user)

firebase functions date query

Im trying to run a cron job to delete old notifications. Following a post on this on medium:
https://medium.com/#varunpvp/how-to-schedule-a-firebase-cloud-function-ded2db0cf9f3
This is where im up to:
const oneMonthOld = admin.firestore.Timestamp.now().toMillis() - 2592000000;
const oldNotifications = await admin.firestore()
.collection('notifications')
.where('createdAt', '>', oneMonthOld);
I've created a document in this collection. I have other queries in the function working against this collection. The article sais that more than is < (?) i've tried both ways round
const results2 = await oldNotifications.get();
results2.forEach(doc => {
console.log('in function');
oldNotificationsBatch.delete(doc.ref);
});
the function neither deletes the record or emits the log in the UI
Can anyone suggested whats going wrong here?

How to Retrieve Data from Out of Axios Function to Add to Array (NEWBIE QUESTION)

I am working on building a blog API for a practice project, but am using the data from an external API. (There is no authorization required, I am using the JSON data at permission of the developer)
The idea is that the user can enter multiple topic parameters into my API. Then, I make individual requests to the external API for the requested info.
For each topic query, I would like to:
Get the appropriate data from the external API based on the params entered (using a GET request to the URL)
Add the response data to my own array that will be displayed at the end.
Check if each object already exists in the array (to avoid duplicates).
res.send the array.
My main problem I think has to do with understanding the scope and also promises in Axios. I have tried to read up on the concept of promise based requests but I can't seem to understand how to apply this to my code.
I know my code is an overall mess, but if anybody could explain how I can extract the data from the Axios function, I think it could help me get the ball rolling again.
Sorry if this is a super low-level or obvious question - I am self-taught and am still very much a newbie!~ (my code is a pretty big mess right now haha)
Here is a screenshot of the bit of code I need to fix:
router.get('/:tagQuery', function(req, res){
const tagString = req.params.tagQuery;
const tagArray = tagString.split(',');
router.get('/:tag', function(req, res){
const tagString = req.params.tag;
const tagArray = queryString.split(',');
const displayPosts = tagArray.map(function(topic){
const baseUrl = "https://info.io/api/blog/posts";
return axios
.get(baseUrl, {
params: {
tag: tag
}
})
.then(function(response) {
const responseData = response.data.posts;
if (tag === (tagArray[0])){
const responseData = response.data.posts;
displayPosts.push(responseData);
} else {
responseData.forEach(function(post){
// I will write function to check if post already exists in responseData array. Else, add to array
}); // End if/then
})
.catch(function(err) {
console.log(err.message);
}); // End Axios
}); // End Map Function
res.send(displayPosts);
});
Node.js is a single thread non-blocking, and according to your code you will respond with the result before you fetching the data.
you are using .map which will fetch n queries.
use Promise.all to fetch all the requests || Promise.allsettled.
after that inside the .then of Promise.all || promise.allsettled, map your result.
after that respond with the mapped data to the user
router.get('/:tag', function (req, res) {
const tagString = req.params.tag;
const tagArray = queryString.split(',');
const baseUrl = "https://info.io/api/blog/posts";
const topicsPromises=tagArray.map((tobic)=>{
return axios
.get(baseUrl, {
params: {
tag: tag
}
})
});
Promise.all(topicsPromises).then(topicsArr=>{
//all the data have been fetched successfully
// loop through the array and handle your business logic for each topic
//send the required data to the user using res.send()
}).catch(err=>{
// error while fetching the data
});
});
your code will be something like this.
note: read first in promise.all and how it is working.

Creating Search/filter in express mongo react

im trying to build a filter menu to filter the incoming data from mongodb.
im using the .find(); function to limit the incoming data.
usage like this
Post.find({boatType: "Cruiser"})
So here is what ive got so far.
I transfer the data that i need to filter via query
const res = await axios.get(`/api/posts/`,
{
params: {
hull: "Catamaran",
boatType: "Cruiser",
seller: "Private",
etc..
}
});
express Backend
const posts = await Post.find({exampleField: "exampleFilter"});
and this is where im stuck. After i pass the queries to the node backend, i have no idea how to get the .find() function to work across multiple fields. and even more confusing for me is that these queries will be dynamic. Sometimes the "hull" query will not be there, or it might be that "seller" is not there, etc etc. Is there a better way to do what im doing? Should i be using $Regex or $in... im lost and the documentation is doing me no favors.
all help is appreciated.
you should just pass your query object to Post.find(), like this:
app.get('/api/posts' , (req, res) => {
// you can access the query from req.query
const posts = await Post.find(req.query);
})
You can check here and here for more details.

Resources