0

I am at a beginner level with the MEAN stack, trying to work on the following tutorial: adrianmejia.com/blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/. I am using Cloud 9 online IDE.

Part of the tutorial involves testing database POST using curl and Postman. I successfully post a GET request, which at this point in the tutorial gives med an empty array.

I use curl -XGET myc9urlhere:8080/todos - with success (getting [])

And try curl -XPOST myc9urlhere:8080/todos -d 'name=Somename&completed=false&note=somenote' - failing

The stacktrace is as follows:

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)

A small note is that I have also tried this using the Chrome extension Postman. The tutorial says I must use x-www-form-urlencoded which gives the same error returned. See screenshot. And if I turn to the form-data setting instead, I actually succeed in inserting some data into the database, but just bogus stuff. See the second screenshot.

Postman fail

Postman form-data

I have really tried to research myself - maybe this tutorial is not the greatest place to start either :). Below I will include some details on the code.

Thanks a lot for any help solving this.

Identical to the tutorial, I have created a Model for a todo-list item, as shown (Todo.js):

var mongoose = require('mongoose');

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

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

Now in my express routing file todos.js I have the following code:

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;

Because I do not know exactly what is wrong here I will also post an extract of my app.js showing my database connection

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

And the package-json that was generated (I am using 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"
  }
}
BenM
  • 38
  • 8

2 Answers2

0

I think the main problem you're encountering here is that all post parameters are strings. This ends up being fine for the name and note fields of you TodoSchema, but will break when it comes to the completed field, since it is boolean. To address this, try converting the string to a boolean before creating the ToDo entry.

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

Also, the reason that the bogus post worked is because you aren't validating your post data. Consider making sure that the post data coming in though your route has all of the required fields, and doesn't contain anything dangerous.

  • Thanks for responding. I have experimented with your suggestion, but the problem persists. I am able to extract the correct values from name, completed and notes from the request body. They all seem correct, except that it seems like the completed parameter is cached or something, as it does not change on the server side immediately when I change it on the client side - it seems to store the old value for a while, that's odd. I tried also just to force a valid boolean to the body parameter, by req.body.completed = true; This also does not remove the validation error. – BenM Jan 08 '17 at 20:28
0

Go to the data folder in your directory. Inside it there is a file mongod.lock. Delete it (you wont require root privileges) just use rm mongod.lock. Come back to main directory and enter ./mongod. hope this will solve the problem

ihoudjedje
  • 95
  • 9