How to fix unhandled promise rejection warning, cast to objectid failed - javascript

I'm new to mongoose, I am trying to set up a get route to '/featured' in my api but am getting the following error '(node:8989) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "featured" at path "_id" for model "Blog"'
I am fairly sure I'm just doing something wrong when setting up my router for my blogs. I've tried using .find({'featured': true}), tried .find({featured: true}), tried .find().where('featured', true), tried .find().where('featured').equals(true) and all of them result in the same UnhandledPromiseRejectionWarning: CastError
here is my blog schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BlogSchema = new Schema({
title: { type: String, required: true },
article: { type: String, required: true },
published: { type: Date, required: true },
featured: { type: Boolean, required: true },
author: { type: Schema.Types.ObjectId, ref: 'User', required:true}
});
module.exports = mongoose.model('Blog', BlogSchema);
here is the route I am having trouble with in blogs.js
router.get('/featured', (req, res) =>
{
Blog
.find({'featured': true})
.then(blogs =>
{
if(blogs){
res.status(200).json(blogs)
}
else console.log('blogs not found');
})
.catch(err => console.log(err));
});
here is the error stack trace
(node:16486) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
Server is listening on http://localhost:8080
(node:16486) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "featured" at path "_id" for model "Blog"
at new CastError (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/error/cast.js:29:11)
at ObjectId.cast (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/schema/objectid.js:244:11)
at ObjectId.SchemaType.applySetters (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/schematype.js:948:12)
at ObjectId.SchemaType._castForQuery (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/schematype.js:1362:15)
at ObjectId.SchemaType.castForQuery (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/schematype.js:1352:15)
at ObjectId.SchemaType.castForQueryWrapper (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/schematype.js:1331:15)
at cast (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/cast.js:307:32)
at model.Query.Query.cast (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/query.js:4575:12)
at model.Query.Query._castConditions (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/query.js:1783:10)
at model.Query.<anonymous> (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/query.js:2038:8)
at model.Query._wrappedThunk [as _findOne] (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/mongoose/lib/helpers/query/wrapThunk.js:16:8)
at process.nextTick (/home/taylour/projects/node200/node200-mongoose-blog-api/node_modules/kareem/index.js:369:33)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
(node:16486) 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(). (rejection id: 1)
I expect to have the "/featured" route return all blogs where the "featured" boolean value is true, but instead I am getting this error no matter what permutations of the query I try for this route

I'm new to mongoose, I am trying to set up a get route to '/featured' in my api but am getting the following error '(node:8989) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "featured" at path "_id" for model "Blog"'
This is saying that you have a document in your mongo collection that looks like {_id: "featured"}. "featured" isn't an ObjectId, so mongoose is erroring when it sees that document because it doesn't know how to handle it.

Related

CastError : try implement a route and right away get error

i do a project in nodejs with express and mongo
now i tried do implement a simple route but i get an error
//this is the route
router.patch('/resetPassword/:token', authController.resetPassword)
//this is the resetPassword function
exports.resetPassword = (req, res, next) => {
console.log("work")
}
But as soon as I click on the request I get the error even the consul.log is not read
C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:4498
const castError = new CastError();
^
CastError: Cast to ObjectId failed for value "resetPassword" (type string) at path "_id" for model "User"
at model.Query.exec (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:4498:21)
at model.Query.Query.then (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:4592:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
messageFormat: undefined,
stringValue: '"resetPassword"',
kind: 'ObjectId',
value: 'resetPassword',
path: '_id',
reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
at new ObjectID (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\bson\lib\bson\objectid.js:59:11)
at castObjectId (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\cast\objectid.js:25:12)
at ObjectId.cast (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\schema\objectid.js:246:12)
at ObjectId.SchemaType.applySetters (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\schematype.js:1123:12)
at ObjectId.SchemaType._castForQuery (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\schematype.js:1601:15)
at ObjectId.SchemaType.castForQuery (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\schematype.js:1591:15)
at ObjectId.SchemaType.castForQueryWrapper (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\schematype.js:1568:20)
at cast (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\cast.js:332:32)
at model.Query.Query.cast (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:4937:12)
at castQuery (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:4738:18)
at model.Query.Query._findAndModify (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:3598:23)
at model.Query.<anonymous> (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\query.js:3164:8)
at model.Query._wrappedThunk [as _findOneAndUpdate] (C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\mongoose\lib\helpers\query\wrapThunk.js:16:8)
at C:\Users\5MATA\Desktop\first-real-project\BOOKS-PROJECT\BOOKS-BACK\node_modules\kareem\index.js:370:33
at processTicksAndRejections (node:internal/process/task_queues:78:11),
valueType: 'string'
}
This is how you do it.
route.js
const router = require("express").Router();
const adminCtrl = require("./adminCtrl");
router.post("/login", adminCtrl.adminLogin);
adminCtrl.js
exports.adminLogin = (req, res,next) => {
}

NodeJS: CastError: Cast to ObjectId failed for value "new" at path "_id" for model "Client"

I am working on a node app. All the routes seem to work up until I add
app.get('/clients/:id',async (req, res) => {
const client = await Client.findById(req.params.id);
res.render('clients/show', {client});
});
When I comment-out the id route, the new route works as expected. But when it's there and I try to hit the "new route" at:
app.get('/clients/new', (req, res) => {
res.render('clients/new')
});
I get the following error:
(node:17216) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "new" at path "_id" for model "Client"
Here is my schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const ClientSchema = new Schema({
company: String,
contact: String,
phone: Number,
email: String,
city: String,
state: String,
zip: Number,
accounts: [
{
type: Schema.Types.ObjectId,
ref: 'Account',
},
]
});
module.exports = mongoose.model('Client', ClientSchema);
I can't seem to find the problem here, any help would be greatly appreciated.
Thanks
You are doing app.get('/clients/new') into path /clients/:id, so in your controller, req.params.id value is new.
Then you are doing const client = await Client.findById(req.params.id);.
That is: You are trying to find a document with _id "new".
ObjectId in mongo has an specific format and "new" can't be casted. This is why the exception is thrown.
To solve this you have two options. Modify the path or modify the value you will send.
If you want to have a path with "new" you can create a new route like this:
app.get('/clients/new/:id')
And send the id at path clients/new/YOUR_ID.
The other options is not call a path with new. Call directly /clients/YOUR_ID.
But remember send a valid ObectId format, so when you read req.params.id you will not face the error.
Check the docs to know how ObjectId works.

Including subschemas in schemas doesn't seem to work for mongoose

This is how I defined my subschema and schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const JobSchema = new Schema ({
jobname: String,
jobstatus: String
})
const DataSchema = new Schema ({
username: {
type: String,
required: true,
unique: true
},
jobs: [JobSchema]
});
module.exports = mongoose.model("data", DataSchema);
This block of code is to utilize the schema above as a model
const express = require("express");
const router = express.Router();
const Data = require("../../models/Data");
router.post("/", (req, res) => {
const newData = new Data({
username: req.body.username,
jobs: req.body.jobs
});
newData
.save()
.then(data => res.json(data))
.catch(err => console.log(err));
});
module.exports = router;
Data I attempted to put in:
{
username: France,
jobs: [{jobname: Google, jobstatus: applied}]
}
Error:
Error: data validation failed: jobs: Cast to embedded failed for value "'[{jobname: Google, jobstatus: applied}]'" at path "jobs"
at ValidationError.inspect (/Users/Desktop/server/node_modules/mongoose/lib/error/validation.js:48:26)
at formatValue (internal/util/inspect.js:723:31)
at inspect (internal/util/inspect.js:289:10)
at formatWithOptionsInternal (internal/util/inspect.js:1918:40)
at formatWithOptions (internal/util/inspect.js:1802:10)
at Object.Console.<computed> (internal/console/constructor.js:304:10)
at Object.log (internal/console/constructor.js:314:61)
at /Users/Desktop/server/routes/api/data.js:14:31
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
errors: {
jobs: CastError: Cast to embedded failed for value "'[{jobname: Google, jobstatus: applied}]'" at path "jobs"
at DocumentArrayPath.cast (/Users/Desktop/server/node_modules/mongoose/lib/schema/documentarray.js:449:19)
at DocumentArrayPath.cast (/Users/Desktop/server/node_modules/mongoose/lib/schema/documentarray.js:378:17)
at DocumentArrayPath.SchemaType.applySetters (/Users/Desktop/server/node_modules/mongoose/lib/schematype.js:1031:12)
at model.$set (/Users/Desktop/server/node_modules/mongoose/lib/document.js:1203:20)
at model._handleIndex (/Users/Desktop/server/node_modules/mongoose/lib/document.js:979:14)
at model.$set (/Users/Desktop/server/node_modules/mongoose/lib/document.js:920:22)
at model.Document (/Users/Desktop/server/node_modules/mongoose/lib/document.js:137:12)
at model.Model (/Users/Desktop/server/node_modules/mongoose/lib/model.js:106:12)
at new model (/Users/Desktop/server/node_modules/mongoose/lib/model.js:4695:15)
at /Users/Desktop/server/routes/api/data.js:7:21
at Layer.handle [as handle_request] (/Users/Desktop/server/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/Desktop/server/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/Desktop/server/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/Desktop/server/node_modules/express/lib/router/layer.js:95:5)
at /Users/Desktop/server/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/Desktop/server/node_modules/express/lib/router/index.js:335:12) {
stringValue: `"'[{jobname: Google, jobstatus: applied}]'"`,
messageFormat: undefined,
kind: 'embedded',
value: "'[{jobname: Google, jobstatus: applied}]'",
path: 'jobs',
reason: ObjectParameterError: Parameter "obj" to Document() must be an object, got [{jobname: Google, jobstatus: applied}]
at EmbeddedDocument.Document (/Users/Desktop/server/node_modules/mongoose/lib/document.js:90:11)
at EmbeddedDocument [as constructor] (/Users/Desktop/server/node_modules/mongoose/lib/types/embedded.js:42:12)
at new EmbeddedDocument (/Users/Desktop/server/node_modules/mongoose/lib/schema/documentarray.js:115:17)
at DocumentArrayPath.cast (/Users/Desktop/server/node_modules/mongoose/lib/schema/documentarray.js:442:22)
at DocumentArrayPath.cast (/Users/Desktop/server/node_modules/mongoose/lib/schema/documentarray.js:378:17)
at DocumentArrayPath.SchemaType.applySetters (/Users/Desktop/server/node_modules/mongoose/lib/schematype.js:1031:12)
at model.$set (/Users/Desktop/server/node_modules/mongoose/lib/document.js:1203:20)
at model._handleIndex (/Users/Desktop/server/node_modules/mongoose/lib/document.js:979:14)
at model.$set (/Users/Desktop/server/node_modules/mongoose/lib/document.js:920:22)
at model.Document (/Users/Desktop/server/node_modules/mongoose/lib/document.js:137:12)
at model.Model (/Users/Desktop/server/node_modules/mongoose/lib/model.js:106:12)
at new model (/Users/Desktop/server/node_modules/mongoose/lib/model.js:4695:15)
at /Users/Desktop/server/routes/api/data.js:7:21
at Layer.handle [as handle_request] (/Users/Desktop/server/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/Desktop/server/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/Desktop/server/node_modules/express/lib/router/route.js:112:3)
}
},
_message: 'data validation failed'
}
I have read from several sources on the internet that the idea of subschemas(a.k.a subdocuments) is possible. However, when I try to implement it as shown above, it fails to work. What is the reason behind this?
The error looks like you are assigning a string to jobs instead of the array object. I think what you are currently saving is
{
username: "France",
jobs: "[{jobname: Google, jobstatus: applied}]" // the whole array as string
}
What you should be saving is
{
username: "France",
jobs: [{jobname: "Google", jobstatus: "applied"}]
}
Please console log the req.body.jobs and check if its a proper JSON array
You can't use schema in another schema by storing it in a "jobs".
You can give a reference to "jobschema" as below.
jobs : [{
type: Schema.ObjectId,
ref: 'JobSchema'
}]

Mongo db data insertion issue

I am getting this error when i am trying to insert anything into Mongo db. Any help would be appreciated.
const mongoose = require('mongoose');
const dbpath = "mongodb+srv://cluster0-bm7js.mongodb.net/classic";
mongoose.connect(dbpath, {useUnifiedTopology: true , useNewUrlParser: true })
.then(()=> console.log("Now connected to MongoDB!"))
.catch(err=> console.error("Something went wrong", err));
const gameSchema = new mongoose.Schema( {
title: String,
publisher: String,
tags: [String],
date: {
type: Date,
default: Date.now
},
onSale: Boolean,
price: Number
});
const Game = mongoose.model('Game', gameSchema);
async function saveGame() {
const game = new Game( {
title: "Tekken 3",
publisher: "Neogeo",
tags: ["adventure", "action"],
onSale: false,
price: 69.99,
});
const result = await game.save();
console.log(result);
}
saveGame();
This is my code and the error i am getting after running the above code is as,
(node:94819) UnhandledPromiseRejectionWarning: MongoError: user is not allowed to do action [insert] on [classic.games]
at Connection.<anonymous> (/Users/thinkun/Desktop/mongo/node_modules/mongodb/lib/core/connection/pool.js:466:61)
at Connection.emit (events.js:198:13)
at processMessage (/Users/thinkun/Desktop/mongo/node_modules/mongodb/lib/core/connection/connection.js:364:10)
at TLSSocket.<anonymous> (/Users/thinkun/Desktop/mongo/node_modules/mongodb/lib/core/connection/connection.js:533:15)
at TLSSocket.emit (events.js:198:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at TLSSocket.Readable.push (_stream_readable.js:224:10)
at TLSWrap.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
(node:94819) 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(). (rejection id: 1)
(node:94819) [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.
Not sure why Mongo db is unable to help me working inside.
Thanks in advance.
const mongoose = require('mongoose');
const dbpath = "mongodb+srv://cluster0-xxxx.mongodb.net/Game";
mongoose.connect(dbpath, {user: 'username', pass: 'password'})
.then(()=> console.log("Now connected to MongoDB!"))
.catch(err=> console.error("Something went wrong", err));
There was an issue with Connection string. All sorted with username and password.

Loading express template with a passed variable returns error `Cannot set headers after they are sent to the client`

I have a form and I am trying to validate it with express-validator. When there are no validation errors, I get no error in the console, but when there are validation errors I try to pass them to my EJS template, but it gives me an error in the console. This is my full code:
var express = require('express');
var app = express();
var path = require('path');
var mongoose = require('mongoose');
var bodyParser = require('body-parser')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}))
const { check, validationResult } = require('express-validator');
app.listen(8080);
// saytin asuma inch template piti ogtagorcvi
app.set('view engine', 'ejs');
// MongoDB
let dbUrl = 'mongodb+srv://grig:xxxXXXxxx#cluster0-osvfl.mongodb.net/test?retryWrites=true&w=majority';
mongoose.connect(dbUrl ,{useNewUrlParser : true},(err) => {
if (err) {
console.log(err);
}
});
var schema = new mongoose.Schema({ name: 'string', message: 'string' });
var User = mongoose.model('User', schema);
//
// router
app.get('/', function(req, res) {
res.render('index');
});
app.use(express.json());
app.post('/send', [
check('name').isLength({ min: 1 }).withMessage('Անունը չի կարող դատարկ լինել'),
check('message').isLength({ min: 10 }).withMessage('Նամակը պետք է լինի 10 սիմվոլից ավել')
], (req, res) => {
// Uxarkel errornery
const errors = validationResult(req);
if (!errors.isEmpty()) {
res.render('index',{
errors: errors
});
}
// Stexcel userin
User.create({
name: req.body.name,
message: req.body.message
}).then(user => res.json(user));
});
//
And here's the error that I'm getting:
(node:6244) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (C:\xampp\htdocs\node\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\xampp\htdocs\node\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\xampp\htdocs\node\node_modules\express\lib\response.js:267:15)
at User.create.then.user (C:\xampp\htdocs\node\server.js:51:23)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:6244) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecti
ng a promise which was not handled with .catch(). (rejection id: 1)
(node:6244) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process wit
h a non-zero exit code.
I'm new to Node, so can you please explain what causes the error. Thanks.
if (!errors.isEmpty()) {
res.render('index',{
errors: errors
});
}
else {
// Stexcel userin
User.create({
name: req.body.name,
message: req.body.message
}).then(user => res.json(user))
}
The else part of code was getting executed, even if there was error, and it was trying to send the response again. thus you were getting that error. Or you can a return when you are sending error, it will resolve the issue.

Categories

Resources