Mongoose find() returns an empty doc - node.js

why does this function return an empty document? There is an other function that uses find({}) without any query and it works.
router.get('/mesCandidatures/:id', function(req, res, next) {
Models.Candidature.find({"figurant":req.params.id}, function(err,docs) {
if (err){
throw err;
}else{
res.send(docs);
}
});
});
I send this parameter: 59e5d09f853d00049fd67600
I am supposed to receive this:
{
"_id":"59ea0d1fea79bf099696fcab",
"etat":"validé",
"figurant":"59e5d09f853d00049fd67600",
"offre":"59e5bc1438950e01ae45d1d2"
}`
Thanks

Your problem might be caused by filtering with an incorrect field type figurant
Your req.params.id is a string, while i am guessing that figurant is defined in your schema as type ObjectId, so you need to filter by ObjectId not a string
Change your code to be :
var mongoose = require('mongoose');
router.get('/mesCandidatures/:id', function(req, res, next) {
Models.Candidature.find({"figurant":mongoose.Types.ObjectId(req.params.id)}, function(err,docs) {
if (err){
throw err;
}else{
res.send(docs);
}
});
});

What you have in your code is an instance of Query returned in a callback, so in case of find() you have to use exec() for mongoose to know when it has to be executed, so your request should be
router.get('/mesCandidatures/:id', function(req, res, next) {
Models.Candidature.find({ figurant: req.params.id }).exec( function(err,docs) {
if (err){
throw err;
}else{
res.send(docs);
}
});
});
But originally you use find() when you need to get a list of a documents, if you need a single document you can use findOne() that instead of query returns you a potentially-null single document. Then you can get your callback as you did:
router.get('/mesCandidatures/:id', function(req, res, next) {
Models.Candidature.findOne({ figurant: req.params.id }, function(err,docs) {
if (err){
throw err;
}else{
res.send(docs);
}
});
});
Also, you don't have to use a quotes for your condition unless you are not getting nested fields with paths like "nested.field"

Related

req.params.id is undefined, I can't figure out why

Here is the url in browser:
http://localhost:3001/user/59cc018171149931f4e435ac
This is the code for the route:
router.get("/new", middleware.userLoggedIn, function(req, res){
console.log(req.params.id);
//find user by id
User.findById(req.user._id, function(err, foundUser){
if(err) {
console.log(err);
} else {
res.render("characters/addCharacter", {user: foundUser});
}
});
});
This is the middleware:
middlewareObj.userLoggedIn = function(req, res, next) {
// eval(require('locus'));
if (req.isAuthenticated() && req.params.id.equals(req.user._id)) {
return next();
}
res.redirect("/login");
};`
When I run the app everything works fine. Expect the request on the route above, wich giving me the error "TypeError: Cannot read property 'equals' of undefined". When I take off the middleware and try to console.log(req.params.id), it returns "undefined". What am I doing wrong?
Edit:
I have my route configured in app.js:
app.use("/user/:id/characters", characterRoutes);
So the ":id" is there.
When i use /new/:id instead of /new geting new error message:
"Cannot GET /user/59c23b864262fc2c186677be/characters/new"
use /new/:id instead of /new
router.get("/new/:id", middleware.userLoggedIn, function(req, res){
console.log(req.params.id);
//find user by id
User.findById(req.user._id, function(err, foundUser){
if(err) {
console.log(err);
} else {
res.render("characters/addCharacter", {user: foundUser});
}
});
});
You have to specify the parameter you want in your path, like so /new/:id and then you can use req.params.id in your code.
Here's the Express documentation for this part
cast req.params into any first:
let params: any = req.params
and then params.id should work

GET request for specific id returning null

I'm attempting to build a simple CRUD application using express and mongodb. My GET request for all database entries is working and my POST request is working but I can't seem to figure out the problem with my GET request for individual entries.
Server.js GET request:
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: id}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
When I type 'url/api/593555074696601afa192d7f' which is an ID I know exists the console.log is returning null, I'm not sure if I'm doing something wrong?
You should pass ObjectID instance in the query.
let ObjectID = require("mongodb").ObjectID;
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: ObjectID(id)}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
Give Mongoose a try. It might be of help if your models get complex.

MEAN stack application - querying by userId

I have built an API to GET and POST values into a database(MongoDB) using NodeJS and Express.
I am able to get only a single comment by the userid
(localhost:3000/comments/userid/3)
But I want to get all comments by a single user
/* GET /comments/userid/userid */
router.get('/userid/:userid', function(req, res, next) {
Comments.findOne({userId:req.params.userid}, function (err, post) {
if (err) return next(err);
res.json(post);
})
});
Is there any method to do this? Like the findOne method?
just do find with the query
router.get('/userid/:userid', function(req, res, next) {
Comments.find({userId:req.params.userid}, function (err, post) {
if (err) return next(err);
res.json(post);
})
});

Mongoose middleware post update not working

Callback is not being called, but it should as per documented in mongoose middleware:
schema.post('update', function(error, res, next) {
if (error.name === 'MongoError' && error.code === 11000) {
next(new Error('There was a duplicate key error'));
} else {
next(error);
}
});
I tried pre update and it works:
schema.pre("update", function(next) {
console.warn('results', "i am called");
next(new Error("error line called"));
});
But what I wanted is post update:
schema.post("update", function(error, res, next) {
console.warn('results', "is this called?");
});
The actual model update:
MyModel.update({_id : 123}, req.payload, function (err, numberAffected, rawResponse) {
reply("done!");
});
I am not seeing the log console.warn('results', "is this called?");, is this expected?
p.s:
Machine: windows 10,
mongoose version: 4.5.8
Going by the docs, it looks like you should only have one argument in the schema.post's callback function that represents the document that was updated. It's likely that your callback is never being invoked by the hook because it's never supplied the rest of the arguments. e.g:
schema.post("update", function(doc) {
console.log('Update finished.');
});
instead of:
schema.post("update", function(error, res, next) {
console.log('Update finished.');
});

Mongoosedb: query by username

Problem Question: I am using MongooseDB with Nodejs and I have user schema
var UserSchema = new mongoose.Schema({
userEmail: String
});
how would I query using the userEmail?
I tried following but no result. On my postman i get cast to ObjectId failed error
router.get('/:userEmail', function(req, res, next) {
User.find(req.params.userEmail, function (err, userDetails) {
if(err){
return next(err);
}res.json(userDetails);
})
});
You need to create a query object or document that has the userEmail property and a value from the req.params object. In your case, this would be:
router.get('/:userEmail', function(req, res, next) {
User.find({ "userEmail": req.params.userEmail }, function(err, userDetails) {
if(err){
return next(err);
}
res.json(userDetails);
});
});
Please try this syntax
router.get('/:userEmail', function(req, res, next) {
User.find({"userEmail":req.params.userEmail}, function (err, userDetails) {
if(err){
return next(err);
}res.json(userDetails);
})
});
You have to put condition on which field you want to query data.
I am unable to reproduce your error "ObjectId failed error". However, I am adding another answer to give you more options.
The following things are slightly different from other answers:-
1) "lean()" is used to ensure that you will be returned a plain JavaScript object
2) Excluded the "_id" from JSON response though I am not sure whether you need the "Id" in the response. This is just to check whether "id" in response is causing the problem.
router.get('/:userEmail', function(req, res, next) {
User.find({"userEmail": req.params.userEmail}, {"_id":false}).lean().exec(function(err, users) {
if (err) {
return next(err);
}
console.log(users);
res.json(users);
});
});

Resources