findById not working in mognodb with nodejs - node.js

This is my code;
I'm try for update user data. like so you are seen this code. But result coming null.
I'm not understand. please help me guys
// #Router UPDATE /updateforslip/:id
// #desc UPDATE update by ID
// #access Private
router.put('/update/user/data/:id', async (req, res) => {
var update = Pan.findByIdAndUpdate(req.params.id, {
$set: req.body
})
console.log(update)
update.exec((error, data) => {
if (error) throw error;
res.json(data)
})
})
Coming result
in console.log(update)
null
I'm using postman for request.

try this:
router.put('/update/user/data/:id', async (req, res) => {
tyr{
var update = await Pan.findByIdAndUpdate(req.params.id, {$set: req.body})
res.json(update)
}catch (err){
throw error;
}

Just try like this, don’t use exec() when you want to uae async await
and use try/carch for handling errors
try{
var data = await Pan.findByIdAndUpdate(req.params.id, {
$set: req.body
}).lean();
res.json(data)
},
catch(error){
}

Related

MongoDB Atlas/Cloud retrieving data from _id

I am creating a project with MongoDB Atlas/Cloud and I have the method to obtain ALL the data of a database that I have created from the cloud.
This is how I did it:
router.get('/', (req, res) => {
// http://localhost:3000/data
client.connect(async err => {
if (await err) {
console.log("Error connecting to MongoDB Cloud:\n\t" + err.toString());
}
console.log("Connected to the DB!");
const collectionData = client.db("myDatabase").collection("data");
try {
const data = await collectionData.find().toArray();
console.log(data);
res.json(data);
} catch (e) {
res.json({message: e});
}
await client.close();
});
});
But I would like to be able to collect each data individually by introducing its _id in the URI. This is how I tried to do it:
router.get('/:dataID', (req, res) => {
// http://localhost:3000/data/<ID>
client.connect(async err => {
if (await err) {
console.log("Error connecting to MongoDB Cloud:\n\t" + err.toString());
}
console.log("Connected to the DB!");
const collectionData = client.db("myDatabase").collection("data");
try {
console.log(req.params.dataID); // It works, it prints the _id
const specificData = await collectionData.findById(req.params.dataID).toArray();
console.log(specificData);
res.json(specificData);
} catch (e) {
res.json({message: e});
}
await client.close();
});
});
But it doesn't work. I'm retrieving a blank object: message: {}. I've checked the _id introduced, it's exactly the same as the _id from the mongoDB object that I'm trying to retrieve. What am I doing wrong? It should be the const specificData = await collectionData.findById(req.params.dataID).toArray(); but I don't know what to change to make it work right.
P.S.: After making a GET petition to the server to /data, I get the data, but if I try to make another petition after that, I get an MongoDB Error, do anyone know why is this happening? Thank you in advance
Solved:
const specificData = await collectionData.find(req.params.dataID).toArray();
console.log(specificData.get[0]);

Sorting A-Z/Date data from router.get?

Quick question: how can I sort my posts data by date?
router.get('/', async (req, res) => {
try {
const posts = await Post.find()
res.json(posts)
}
catch (err) {
res.json({message: err})
}
})
I came from Django and there you could do something like:
posts = Post.objects.filter().order_by('date')
I'm fairly new to NodeJS and Express. Thanks a lot!
It depends on the what the data structure of the date property is. If they are in JS timestamp format:-
router.get('/', async (req, res) => {
try {
const posts = await Post.find();
const sortedPosts = posts.sort((a,b) => {
return new Date(b.date) - new Date(a.date);
});
res.json(sortedPosts)
}
catch (err) {
res.json({message: err})
}
})
Here I've used the array's sort() method. Learn more

Mongoose find not returning the full collection

I am trying to read data from an html form through a POST, store it in a mongoDB and query it using model.find() and print it in console. But when i run this for the first time the find() is returning an empty object and on giving the next input the previous data excluding the current input is retrieved by th find(). How can i print the full collection including the freshly entered data
app.post("/", function(req, res){
postTitle = req.body.postTitle;
postDesc = req.body.postDesc;
const post = new Post({
title:postTitle,
desc:postDesc
});
post.save();
Post.find({}, function(err, data){
if(err){
console.log(err);
}else{
console.log(data);
}
});
//console.log(postTitle, postDesc);
});
The command post.save(); will just begin working and your code will continue meanwhile. When your Post.find({} ... starts working, your post.save(); haven't finished working, and thus you're not getting the results.
Change the function so you wait for the save to give you a callback with an ok and then you can query the database.
app.post("/", function(req, res) {
const postTitle = req.body.postTitle;
const postDesc = req.body.postDesc;
const post = new Post({
title: postTitle,
desc: postDesc
});
post.save(function(err) {
if (err) {
// Something went wrong with the save, log and return the error message
console.error(err);
return res.send(err);
}
console.log(`Post "${postTitle}" saved to database.`);
// Since we know that the post has been saved, continue querying the database.
Post.find({}, function(err, data) {
if (err) {
// Something went wrong with the query, log and return the error message
console.error(err);
return res.send(err);
}
console.log(data);
res.send(data);
});
});
});
This code is not tested.
You can also try async/await out, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function and also mongoose documentation for promises & async/await https://mongoosejs.com/docs/promises.html.
I myself would write the function like this using async/await and es6.
app.post('/', async(req, res) => {
const post = new Post({
title: req.body.postTitle,
desc: req.body.postDesc
});
try {
await post.save();
const posts = await Post.find();
console.log(posts);
} catch (err) {
console.error(err);
}
res.end();
});
You can try with exec
Post.find({}).exec(function (err, d) {
if(err){
console.log(err);
}else{
console.log(d);
}
});
Or try to use async await to make sure your query is running step by step
const user_info = await Post.find({});
This code is not tested
here post.save() is an async function that means it does not complete immediately. You need to use async - await in order to wait for the save() function to finish and then you query the database.

Why does my register user post request fail with a 500 error?

I'm building an app with React and Node/Express, and I'm having trouble with my register user function. The data I am passing in is correct, and other endpoints work fine. The register one keeps returning a 500 error and I can't figure out why.
This is my request:
console.log(values)
axios
.post(
'https://foodtrackr-backend.herokuapp.com/api/register',
values
)
.then(res => {
console.log('res.data', res.data);
})
.catch(error => {
console.log('nope');
console.error(error);
});
};
and this is my endpoint:
router.post('/register', async (req, res) => {
let user = req.body;
const newUser = await Users.add(user);
try {
if (newUser) {
res.status(201).json(user);
} else res.status(404);
} catch (error) {
res.status(500).json('noooooo');
}
});
and this is my model:
function findById(id) {
return (
db('users')
.where({ id })
.first()
);
}
async function add(user) {
const [id] = await db('users').insert(user, 'id');
return findById(id);
}
Any help would be appreciated!

I want to increment many documents in mongodb

router.put('/stockAccepted/:id', (req, res, next) =>{
stockSchema.findOneAndUpdate({_id: req.params.id}, {
$set:{
stockAccepted: req.body.stockAccepted
}
},(err, result) => {
if(err) res.json(err);
else res.json(result);
});
let stockItem = req.body.stockItem;
stockItem.forEach((element) => {
console.log("counter")
productSchema.update({_id: element.productId}, {
$inc:{
productQuantity: element.productQuantity
}
}
,(err, result) => {
if(err) res.json(err);
else res.json(result);
});
});
});
what is the best approach to achieve it?
This code throws an error that "headers are already sent".
How can I implement this correctly?
The problem is you are trying to send a JSON response in each db update callback. You can only send a response once for a request. You can either use Promise.all to wait for the stock and product(s) to be updated, or use Mongoose's bulkWrite feature.
The bulkWrite is more efficient as it only involves one request to the DB rather than multiple.
Here is an (untested) example of how bulkWrite could work with your code:
router.put('/stockAccepted/:id', (req, res, next) => {
stockSchema.findOneAndUpdate({
_id: req.params.id
}, {
$set: {
stockAccepted: req.body.stockAccepted
}
}).then((result) => {
let stockItem = req.body.stockItem;
let updates = []
stockItem.forEach((element) => {
updates.push({
updateOne: {
filter: {
_id: element.productId
},
update: {
$inc: {
productQuantity: element.productQuantity
}
}
}
})
})
return productSchema.bulkWrite(updates)
}).then((result) => {
res.json(result);
}).catch((err) => {
res.json(err);
})
});
I'm using the promise returned from a DB call in mongoose rather than the callbacks, as it reduces nesting.
Unlike your version, this code will wait for stock to be updated in DB. Then it will create a bulk operation and send that to the DB. Once this is completed, it will finally return the response from the bulk operation as JSON.
Note that the final catch handler will catch errors in both the stock update, or the bulk product update.
You are iterating over stockItem with a forEach loop, nothing wrong about that.
What you probably miss here is that after handling correctly the first element you use directly the res params which is why the next iteration when you process the same logic it fails with "headers are already sent" because you indeed, already fire an http response with res.
What I suggest is to aggregate your result during the loop and only fire the res with your aggregate results as json as below :
router.put('/stockAccepted/:id', (req, res, next) =>{
stockSchema.findOneAndUpdate({_id: req.params.id}, {
$set:{
stockAccepted: req.body.stockAccepted
}
},(err, result) => {
if(err) res.json(err);
else res.json(result);
});
let stockItem = req.body.stockItem;
const results = [];
const errors = [];
stockItem.forEach((element) => {
console.log("counter")
productSchema.update({_id: element.productId}, {
$inc:{
productQuantity: element.productQuantity
}
}
,(err, result) => {
if(err) errors.push(err);
else result.push(result);
});
});
res.json({
results,
errors
});
});

Resources