I'm a very beginner of Nodejs, not sure I can ask such an easy thing here. When I built a node server to connect to mongodb, got this error:
Cast to Number failed for value "NaN" at path "count"
But, the error is gone in few minutes and the server is running again somehow as well as the count schema was inserted.
I can't find something what made it run again. I just assumed for the reason that my node server couldn't get the value because the "count" schema disappeared.
But could you help me to think in better ways.
Here is the error what I had before.
> db.datas.find()
{ "_id" : ObjectId("5cb39eca6e5e3971fa934a2d"), "name" : "myData", "__v" : 0 }
Data ERROR: save: { ValidationError: data validation failed: count: Cast to Number failed for value "NaN" at path "count"
at ValidationError.inspect (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/error/validation.js:59:24)
at formatValue (util.js:430:38)
at inspect (util.js:324:10)
at format (util.js:253:18)
at Console.log (console.js:130:21)
at /home/gkh/Desktop/Dev/myapp/app.js:46:30
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/model.js:4675:16
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/utils.js:255:11
at $__save.error (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/model.js:471:16)
at /home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:246:48
at next (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:167:27)
at next (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:169:9)
at Kareem.execPost (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:217:3)
at _handleWrapError (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:245:21)
at /home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:272:14
at _next (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:94:14)
errors:
{ count:
{ CastError: Cast to Number failed for value "NaN" at path "count"
at new CastError (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/error/cast.js:29:11)
at model.$set (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/document.js:1073:7)
at model.set [as count] (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/helpers/document/compile.js:140:26)
at /home/gkh/Desktop/Dev/myapp/app.js:44:15
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/model.js:4675:16
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/query.js:4184:12
at process.nextTick (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/query.js:2741:28)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
message: 'Cast to Number failed for value "NaN" at path "count"',
name: 'CastError',
stringValue: '"NaN"',
kind: 'Number',
value: NaN,
path: 'count',
reason: [Object] } },
_message: 'data validation failed',
name: 'ValidationError' }
mongoose.connect("mongodb://localhost:27017/user-node");
var mongod = mongoose.connection;
mongod.once("open", function(){
console.log("DB connected!");
});
mongod.on("err", function(err){
console.log("DB err: ", err);
});
var dataSchema = mongoose.Schema({
name:String,
count:Number
});
var Data = mongoose.model('data', dataSchema);
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR: ", err);
if(!data){
Data.create({name:"myData",count:0}, function(err, data){
if(err) return console.log("Data ERROR", err);
console.log("Counter initialized: ", data);
});
}
});
app.set("view engine", 'ejs');
app.use(express.static(path.join(__dirname + '/public')));
// callback function list
// render to firstPage.ejs page with params or non-params
app.get('/', function(req, res){
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR : /path: ", err);
data.count++;
data.save(function(err){
if(err) return console.log("Data ERROR: save: ", err);
res.render('firstPage', data);
});
});
});
// set count to 0
app.get('/reset', function(req, res){
setCounter(res, 0);
});
// check arg in req.query.count
app.get('/set/count', function(req, res){
if(req.query.count) setCounter(res, req.query.count);
else getCounter(res);
});
// placeholder : num
// any arg can place in num param
app.get('/set/:num', function(req, res){
if(req.params.num) setCounter(res, req.params.num);
else getCounter(res);
});
function setCounter(res, num){
console.log("...setCounter...");
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR: ", err);
data.count=num;
data.save(function(err){
if(err) return console.log("Data ERROR: ", err);
res.render('firstPage', data);
});
});
}
function getCounter(res){
console.log("...getCounter...");
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR", err);
res.render('firstPage', data);
});
}
If I'm wrong or my code is wrong, please advice for me. Thank you in advance!
Set a default value of 0 on the field before doing any operation. This error is coming because there is no initial value assigned to the fields.
Cast to Number failed for value "NaN" at path "count"
This is possible, if the document in the db doesn’t have count attribute.
const Data = mongoose.model('data', dataSchema);
Data.findOne({ name: "myData" }, function (err, data) {
if (err)
return console.log("Data ERROR: ", err);
if (!data) {
Data.create({ name: "myData", count: 0 }, function (err, data) { //correct
if (err)
console.log("Counter initialized: ", data);
return console.log("Data ERROR", err);
});
}
});
Though you have rightly created for the new records, I suspect it might be missing for few legacy records and might be having following structure
db.datas.find()
{ "_id" : ObjectId("5cb39eca6e5e3971fa934a2d"), "name" : "myData", "__v" : 0 }
So, when you make a call to localhost:3000/
, the document’s count
will be undefined
hence when you data.count++
and save, it errors out.
You need to check for undefined
and then update it.
app.get('/', function (req, res) {
Data.findOne({ name: "myData" }, function (err, data) {
if (err) {
return console.log("Data ERROR : /path: ", err);
}
if (!data.count) {
// for legacy records which doesn’t have this attribute
data.count = 0;
}
data.count++;
data.save(function (err) {
if (err) {
return console.log("Data ERROR: save: ", err);
}
res.render('firstPage', data);
});
});
});
Also, Since you are using mongoose for checking and updating a document. You can consider using findOneAndUpdate()
Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback. The query executes if callback is passed else a Query object is returned.
function setCounter(res, num) {
return Data.findOneAndUpdate({
name: 'myData'
}, {
count: num
}, {
new: true,
upsert: false
// if you don't want to create a new document if the record doesnt exist
}).then(doc => {
res.render('firstPage', doc);
}).catch(err => {
return console.log("Data ERROR: ", err);
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With