(node:9540) UnhandledPromiseRejectionWarning: MongooseError: Query was already executed: User.countDocuments({})
at model.Query._wrappedThunk [as _countDocuments] (D:\Acadamic-LANGUAGE-PROJECTS\Angular-Projects\eShop-MEAN STACK\Back-End\node_modules\mongoose\lib\helpers\query\wrapThunk.js:21:19)
at D:\Acadamic-LANGUAGE-PROJECTS\Angular-Projects\eShop-MEAN STACK\Back-End\node_modules\kareem\index.js:370:33
at processTicksAndRejections (internal/process/task_queues.js:77:11)
(Use node --trace-warnings ... to show where the warning was created)
(node:9540) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node
process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:9540) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
this is my Code......
router.get(`/get/count`, async (req, res) =>{
const userCount = await User.countDocuments((count) => count)
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
It seems that you are using Mongoose. It seems you are mixing between async-await and callbacks.
Change await User.countDocuments((count) => count) to
await User.countDocuments()
This is because countDocuments() is called using its callback (which passes its result to the callback), while on the other hand, it is also asked to pass its result to the userCount variable using the await command.
This is exactly what this error message is trying to say: hey, you're sending the same query to the database twice ! While, since since v6 of Mongoose, you can only get run query once - ie, either by adding the cbk argument, or using async-await block. Read about it here: https://mongoosejs.com/docs/migrating_to_6.html#duplicate-query-execution
Now let's move ahead to fixing the problem:
I don't completely understand what you're trying to do this in line:
const userCount = await User.countDocuments((count) => count)
I think what you're trying to do is just get the document count. If so, simply drop 'count => count'.
router.get(`/get/count`, async (req, res) =>{
const userCount = await User.countDocuments();
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
If you were to add a filter to the count (which is what the countDocuments gets - a filter; see API here), then you should use the key:value pair form, ie {count: count}.
router.get(`/get/count`, async (req, res) =>{
/* let count; etc. */
const userCount = await User.countDocuments({count: count});
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
Of course you should use a proper try-catch block when using await, to be able to handle the error if thrown.
(Just encountered this problem myself and made some research into it.)
module.exports.getUserCount = async(req,res)=>{
const numberOfUser = await User.countDocuments()
res.send({numberOfUser : numberOfUser});
}
Related
I want to create Product Categories , so i handle it in productController class database call in productCatService class. I added JS promise to this . now it gives following error.
productCatController.js
module.exports.createProductCat = async (request, response)=> {
let result = await productCatService.createProductCat(productCatData);
if (result) {
responseService.successWithData(response, "Product Category Created");
} else {
responseService.errorWithMessage(response, result);
}
}
productCatService.js
module.exports.createProductCat = (productCatData) => {
let productCat = {
name: productCatData.name,
desc: productCatData.desc,
count:productCatData.count,
status : productCatData.status
};
return new Promise((resolve,reject)=>{
ProductCategory.create(productCat).then(result => {
resolve(true);
}).catch(error => {
reject(false)
})
});
}
Error
(node:18808) UnhandledPromiseRejectionWarning: false
(Use `node --trace-warnings ...` to show where the warning was created)
(node:18808) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a p
romise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.
html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:18808) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a no
n-zero exit code.
Never use await without try/catch. You don't have to try/catch every await, but somewhere down the call stack there needs to be a try/catch block.
You don't need try/catch here, just return the promise from ProductCategory.create()...
// productCatService.js
module.exports.createProductCat = (productCatData) => ProductCategory.create({
name: productCatData.name,
desc: productCatData.desc,
count: productCatData.count,
status: productCatData.status
});
...but you definitely need try/catch here, as this function is the bottom of the stack for this operation, and it is responsible for signifying overall success or failure to the caller.
// productCatController.js
module.exports.createProductCat = async (request, response) => {
try {
await productCatService.createProductCat(productCatData);
responseService.successWithData(response, "Product Category Created");
} catch (err) {
responseService.errorWithMessage(response, err);
}
}
Also don't use new Promise() for operations that already are promises. Keep using the promise you already have. Wrapping new Promise() around existing promises is a source of useless bloat, and it can introduce subtle bugs. Avoid.
MongoDB beginner, having trouble getting queries to work. Was following a tutorial of sorts and it was a demo notes app. Their syntax for saving new notes works fine.
However when it comes to printing out the list of notes, there seems to be something wrong in the syntax given to me or something im doing wrong.
const mongoose = require("mongoose");
const url =
"mongodb+srv://Saif:<password>#cluster0.8d2lb.mongodb.net/notes-app?retryWrites=true&w=majority";
mongoose.connect(url, {
useNewUrlParser: true,
});
const noteSchema = new mongoose.Schema({
content: String,
date: Date,
important: Boolean,
});
const Note = mongoose.model("Note", noteSchema);
Note.find({}).then((result) => {
result.forEach((note) => {
console.log(note);
});
mongoose.connection.close();
});
After looking up documentation, the actual syntax of find is a little different where they pass in a callback instead of using promises. But changing that block to use a callback still doesnt work
Note.find({}, (error, data) => {
if (error) {
console.log(error);
} else {
data.forEach((note) => {
console.log(note);
})
}
mongoose.connection.close()
})
Error
TypeError: cursor.toArray is not a function
at model.Query.<anonymous> (D:\Folders\Documents\CS.........
(Use `node --trace-warnings ...` to show where the warning was created)
(node:27108) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:27108) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
.find method from model returns Query object not Cursor
For cursor you need to do .exec
Note.find({}).exec((error, data) => {
if (error) {
console.log(error);
} else {
data.forEach((note) => {
console.log(note);
})
}
mongoose.connection.close()
})
Greetings!
I have a Node-Express endpoint that calls addAdminController.js (Attached Below) to create a new admin.
Everything works well from functionality point of view. However, When you check if user already exists using mongoose FindOne method, it leaves a warning on the console. This however, does not stop the function from running and I'm successfully returning "Email Already in Use" as json object in Postman.
I want to know why i'm seeing this error and what am I doing wrong with Promise Handling. Your help is much appreciated.
addAdminController.js
const adminsModel = require("../../../../models/admins");
const bcrypt = require("bcryptjs");
exports.addAdminController = async (req, res, next) => {
const { name, email, password, role, image, status } = req.body;
//check if user already exists
try {
adminsModel
.findOne({ email }, (err, admin) => {
if (admin) {
res.status(400).json("Email Already in use");
return;
}
})
.exec();
} catch (error) {
return res.status(500).json("Something Went Wrong");
}
//Encrypt Password using Bcrypt
const saltRounds = 12;
const hashPass = bcrypt.hashSync(password, saltRounds);
//Create New Model with Hashed Password
const newAdmin = new adminsModel({
name: name,
email: email,
password: hashPass,
role: role,
image: image,
status: status,
});
// Save new admin user.
try {
await newAdmin.save();
res.json(newAdmin);
return;
} catch (error) {
res.status(400).json("There was an error creating admin user");
}
};
Console Warning
node:18700) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:533:11)
at ServerResponse.header (F:07_Developrs\Github\APIv2\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (F:07_Developrs\Github\APIv2\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (F:\07_Developrs\Github\APIv2\node_modules\express\lib\response.js:267:15)
at exports.addAdminController (F:\07_Developrs\Github\APIv2\routes\api\admins\addAdmin\addAdmin.controller.js:37:19)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:18700) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:18700) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
First of all, you shouldn't be using callback version of findOne function because code below findOne function call will execute before the callback of findOne executes.
As code below the findOne function call depends on whether user already exists or not, await the result of adminsModel.findOne(...) and check findOne function returned a user or not.
Secondly, wrap findOne function call with try-catch block to handle rejected promise.
try {
const user = await adminsModel.findOne({ email });
if (user) {
return res.status(400).json("Email Already in use");
}
// code to run if user doesn't exists
} catch (error) {
return res.status(500).json("Something Went Wrong");
}
I'm using TypeScript to create a Node.js application and I want to retrieve JSON data from an external API. I have a demo version of the code I'm using, can't put my actual codebase up.
private async getData() {
return await Axios.get(
`http://dummy.restapiexample.com/api/v1/employees`
).then(response => {
return response.data;
});
}
getReleaseResults() {
this.getData().then(responseData => {
responseData.data.data.forEach((element: any) => {
console.log(element);
});
});
}
The error message I get is: (node:6068) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined
at C:\Users\Caoilinn.Hughes\OneDrive\Documents\TypeScript Demos\Azure Test Result Email Extension\emailAzureExtension\app\out\js\apiCaller.js:43:36
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:6068) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6068) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
If I don't have the for each and replace it with
console.log(responseData.data.data)
I don't get any issues. FYI the result set has a data property hence the "data.data"
The problem is that you are already returning response.data from your get function and then again you are doing data.data which would not work.
see this. Remove extra data.
getReleaseResults() {
this.getData().then(responseData => {
responseData.data.forEach((element: any) => {
console.log(element);
});
});
}
Add catch block to get the error if there is any. What is the expected response ? try to log it.
return await Axios.get(
`http://dummy.restapiexample.com/api/v1/employees`
).then(response => {
console.log(response);
return response.data;
}).catch(err => console.log(err));
In loopback 3 When i implement async/await in the before save Operation hook
Entry.observe('before save', async (ctx, next) =>{
if(ctx.instance.images){
Entry.upload(ctx.instance.images[0].src).then(data => {
ctx.instance.image = data;
});
}
});
the console print this error
(node:29323) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Callback was already called.
(node:29323) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
How can i get rid of this issue!?
PS. i cant figure out where's that promise, and this message disappear once i remove the async/await.
You need to specify .catch for the Entry.upload promise.
Entry.upload(ctx.instance.images[0].src).then(data => {
ctx.instance.image = data;
}).catch(console.error);
Some older versions of NodeJS probably won't have that error. You need to always use catch for promises, otherwise the app will crash.
Use try/catch block and always return a Promise resolved or rejected when declare async function (or Promise function)
Entry.observe('before save', async (ctx) =>{
try {
ctx.instance.image = await Entry.upload(ctx.instance.images[0].src)
} catch(error){
return Promise.reject(error)
}
return Promise.resolve()
});