Ошибка приведения к номеру для значения «NaN» при ошибке пути, решаемой сервером самостоятельно

#node.js #mongodb

#node.js #mongodb

Вопрос:

Я очень новичок в Nodejs, не уверен, что могу задать здесь такую простую вещь. Когда я создал сервер узла для подключения к mongodb, получил эту ошибку:

Ошибка приведения к номеру для значения «NaN» при «count» пути

Но ошибка исчезла через несколько минут, и сервер снова каким-то образом запускается, а также была вставлена схема подсчета.

Я не могу найти что-то, что заставило его запустить снова. Я просто предположил, что мой сервер узла не смог получить значение, потому что схема «count» исчезла.

Но не могли бы вы помочь мне думать лучше.

Вот ошибка, которая у меня была раньше.

  • Во-первых, не было схемы «подсчета», когда я проверял сбор данных в mongodb.
 > 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' }
 
  • Вот часть app.js файл:
 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);
  });
}
 

Если я ошибаюсь или мой код неверен, пожалуйста, посоветуйте мне.
Заранее благодарю вас!

Комментарии:

1. Это возможно, если значение count равно NaN при сохранении MyData . Можете ли вы показать нам, какую конечную точку вы вызываете? или как setCounter() вызывается?

2. @Sridhar Ошибка возвращается при вызове [ localhost:3000/] . setCounter() Функция вызывается только в /reset , /set/count , /set/:num .

Ответ №1:

Перед выполнением любой операции установите значение по умолчанию 0 в поле. Эта ошибка возникает из-за того, что полям не присвоено начальное значение.

Комментарии:

1. Спасибо @kaushik_pm, сегодня ты спас мой день

Ответ №2:

Ошибка приведения к номеру для значения «NaN» при «count» пути

Это возможно, если документ в БД не имеет атрибута count.

 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);
    });
  }
});
 

Хотя вы правильно создали для новых записей, я подозреваю, что он может отсутствовать для нескольких устаревших записей и может иметь следующую структуру

db.datas.find()
{ «_id»: ObjectId(«5cb39eca6e5e3971fa934a2d»), «name»: «myData», «__v»: 0 }

Итак, когда вы выполняете вызов localhost:3000/ , документ count будет undefined , следовательно, когда вы data.count и сохраните, он выдает ошибку.

Вам необходимо проверить undefined , а затем обновить его.

 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);
    });
  });
});
 

Кроме того, поскольку вы используете mongoose для проверки и обновления документа. Вы можете рассмотреть возможность использования findOneAndUpdate()

Находит соответствующий документ, обновляет его в соответствии с аргументом обновления, передавая любые параметры, и возвращает найденный документ (если таковой имеется) в обратный вызов. Запрос выполняется, если передается обратный вызов, иначе возвращается объект запроса.

 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);
  });
}
 

Комментарии:

1. итак, в основном, эта проблема возникла из-за того, что я не проверил значение «data.count».

2. Как насчет моей функции setCounter, была ли это неэффективная структура? Кроме того, спасибо за вашу помощь. Ваш код очень полезен и прост

3. @yafomars да, вам нужно сделать эту проверку. Ранее setCounter выполнял 2 вызова. 1, чтобы получить записи, и 2, чтобы сохранить их. Но mongodb предлагает findOneAndUpdate , если мы используем это, мы можем выполнить все за один вызов. 🙂