Почему я получаю ошибку ValidationError?

Я нахожусь на начальном уровне со стеком MEAN, пытаясь работать над следующим учебным пособием: adrianmejia.com/blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/. Я использую Cloud 9 онлайн IDE.

Часть учебника включает тестирование базы данных POST с использованием curl и Postman. Я успешно отправляю запрос GET, который на данном этапе в уроке дает пустому массиву med.

я использую curl -XGET myc9urlhere:8080/todos - с успехом (получение [])

И попробовать curl -XPOST myc9urlhere:8080/todos -d 'name=Somename&completed=false&note=somenote' - провал

Трассировка стека выглядит следующим образом:

ValidationError: Todo validation failed
    at MongooseError.ValidationError (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/error/validation.js:23:11)
    at model.Document.invalidate (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/document.js:1486:32)
    at model.Document.set (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/document.js:753:10)
    at model._handleIndex (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/document.js:596:14)
    at model.Document.set (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/document.js:556:24)
    at model.Document (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/document.js:68:10)
    at model.Model (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/model.js:47:12)
    at new model (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/model.js:3250:13)
    at /home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/model.js:1864:51
    at /home/ubuntu/workspace/todo-api/node_modules/mongoose/node_modules/async/internal/parallel.js:27:9
    at eachOfArrayLike (/home/ubuntu/workspace/todo-api/node_modules/mongoose/node_modules/async/eachOf.js:57:9)
    at exports.default (/home/ubuntu/workspace/todo-api/node_modules/mongoose/node_modules/async/eachOf.js:9:5)
    at _parallel (/home/ubuntu/workspace/todo-api/node_modules/mongoose/node_modules/async/internal/parallel.js:26:5)
    at parallelLimit (/home/ubuntu/workspace/todo-api/node_modules/mongoose/node_modules/async/parallel.js:85:26)
    at /home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/model.js:1882:5
    at Function.create (/home/ubuntu/workspace/todo-api/node_modules/mongoose/lib/model.js:1852:17)

Небольшое замечание, что я также попробовал это, используя расширение Почтальон Chrome. Учебник говорит, что я должен использовать x-www-form-urlencoded который дает ту же ошибку, возвращенную. Смотрите скриншот. И если я вместо этого перейду к настройке данных формы, мне действительно удастся вставить некоторые данные в базу данных, но только фиктивные вещи. Смотрите второй скриншот.

Почтальон провал

Форма почтальона-данные

Я действительно пытался исследовать себя - может быть, этот урок не самое лучшее место для начала:). Ниже я приведу некоторые детали кода.

Большое спасибо за любую помощь в решении этого.

Идентично учебнику, я создал модель для элемента списка задач, как показано (Todo.js):

var mongoose = require('mongoose');

var TodoSchema = new mongoose.Schema({
  name: String,
  completed: Boolean,
  note: String
});

module.exports = mongoose.model('Todo', TodoSchema);

Теперь в моем файле экспресс-маршрутизации todos.js у меня есть следующий код:

var express = require('express');
var router = express();
//express.Router() was the original here, that failed on router.get
//as router was then undefined for some reason.

var Todo = require('../models/Todo.js');

/* GET /todos listing. */
router.get('/', function(req, res, next) {
  Todo.find(function (err, todos) {
    if (err) return next(err);
    res.json(todos);
  });
});

/* POST /todos */
router.post('/', function(req, res, next) {
  Todo.create(req.body, function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

module.exports = router;

Поскольку я не знаю точно, что здесь не так, я также опубликую выдержку из моего app.js, показывающего мое соединение с базой данных

var routes = require('./routes/index');
var users = require('./routes/users');
var todos = require('./routes/todos');

var app = express();

// load mongoose package
var mongoose = require('mongoose');
// Use native Node promises
mongoose.Promise = global.Promise;
// connect to MongoDB
mongoose.connect('mongodb://'+process.env.IP+'/todo-api')
  .then(() =>  console.log('connection succesful'))
  .catch((err) => console.error(err));

app.use('/', routes);
app.use('/users', users);
app.use('/todos', todos);

И пакет-JSON, который был создан (я использую Cloud 9 IDE)

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "ejs": "*",
    "express": "3.2.6",
    "mongoose": "^4.7.6"
  }
}

2 ответа

Перейдите в папку данных в вашем каталоге. Внутри него находится файл mongod.lock. Удалите его (вам не требуются права суперпользователя), просто используйте rm mongod.lock. Вернитесь в основной каталог и введите./mongod. надеюсь, что это решит проблему

Я думаю, что основная проблема, с которой вы здесь сталкиваетесь, заключается в том, что все параметры сообщений являются строками. Это в конечном итоге хорошо для name а также note поля тебя TodoSchema, но сломается, когда дело доходит до completed поле, так как оно булево. Чтобы решить эту проблему, попробуйте преобразовать строку в логическое значение перед созданием записи ToDo.

/* POST /todos */
router.post('/', function(req, res, next) {
  req.body.completed = (req.body.completed === 'true');
  Todo.create(req.body, function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

Кроме того, причина того, что фиктивная запись сработала, заключается в том, что вы не проверяете свои данные. Позаботьтесь о том, чтобы данные поста, поступающие через ваш маршрут, имели все обязательные поля и не содержали ничего опасного.

Другие вопросы по тегам