Cedric Bongaerts Cedric Bongaerts - 6 months ago 15
Node.js Question

Cannot POST (Commenting on a post) | Mongodb with mongoose

I'm building an app in NodeJS/Express combined with Mongodb, where I want to be able to comment to a post but I keep getting a 404 not found.

I setup the models and routes in my server.js and also setup the 'ref' between the two but this is the response I keep getting:

Post Request
And as you can see with the following, the 'capture' aka 'post' does actually exist:

capture

Edit: Made some changes to my initial code with the answers that Zen gave me.

This is my code:

-server.js

// Init Express Web Framework
var express = require('express');
var app = express();
var path = require('path');


// Set view engine to EJS & set views directory
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.set('views', path.resolve(__dirname, 'client', 'views'));

app.use(express.static(path.resolve(__dirname, 'client')));

// Database Connection
var mongoose = require('mongoose');
var configDB = require('./server/config/database.js');
require('./server/routes/capture');
require('./server/routes/comment');
mongoose.connect(configDB.url);

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.text());
app.use(bodyParser.json({ type: 'application/json'}));

// Main route
app.get('/', function(req, res){
res.render('index.html');
});
// API
var api = express.Router();
require('./server/routes/capture')(api);
require('./server/routes/comment')(api);
app.use('/api', api);

// Port Settings
app.listen(process.env.PORT || 3000, process.env.IP);
console.log('Listening on port ' + process.env.PORT);


-capture.js model:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var captureSchema = Schema({
birdname: {type: String, required: true},
place: String,
userId: String,
author: String,
picture: Schema.Types.Mixed,
created_at: Date,
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment'}]
});

module.exports = mongoose.model('Capture', captureSchema);


-capture.js route:

var Capture = require('../models/capture');

module.exports = function(router) {
router.post('/captures', function(req, res){
var capture = new Capture();
capture.birdname = req.body.birdname;
capture.place = req.body.place;
capture.userId = req.body.userId;
capture.author = req.body.author;
capture.picture = req.body.picture;
capture.created_at = new Date();


capture.save(function(err, data){
if(err)
throw err;
console.log(req.body);
res.json(data);
});
});

router.get('/captures', function(req, res){
Capture.find({}, function(err, data){
if(err)
throw err;
res.json(data);
});
});

router.delete('/captures', function(req, res){
Capture.remove({}, function(err){
res.json({result: err ? 'error' : 'ok'});
});
});

router.get('/captures/:id', function(req, res){
Capture.findOne({_id: req.params.id}, function(err, data){
if(err)
throw err;
res.json(data);
});
});

router.delete('/captures/:id', function(req, res){
Capture.remove({_id: req.params.id}, function(err){
res.json({result: err ? 'error' : 'ok'});
});
});
};


-capture.js model:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var commentSchema = Schema({
birdname: String,
body: {type: String, required: true},
userId: {type: String, required: true},
author: {type: String, required: true},
created_at: Date,
capture: [{ type: Schema.Types.ObjectId, ref: 'Capture'}]
});

module.exports = mongoose.model('Comment', commentSchema);


-comment.js route:

var Comment = require('../models/comment');

module.exports = function(router) {
router.post('/captures/:capture/comments', function(req, res, next){
var comment = new Comment();
comment.birdname = req.body.birdname;
comment.body = req.body.body;
comment.userId = req.body.userId;
comment.author = req.body.author;
comment.created_at = new Date();
comment.capture = capture;

comment.save(function(err, comment) {
if (err) { return next(err); }

req.capture.comments.push(comment);
req.capture.save(function(err, capture) {
if (err) { return next(err); }

res.json(comment);
});
});
});
};


Any help is much appreciated..
Thanks

Answer

I would work with one route script, seeing that your comments are attached to the post. You also have to add a Map logic to the route parameters for cature and comment.

Try the following:

var Capture = require('../models/capture');
var Comment = require('../models/comment');

module.exports = function(router) {
    router.post('/captures', function(req, res){
        var capture = new Capture();
        capture.birdname = req.body.birdname;
        capture.place =  req.body.place;
        capture.userId = req.body.userId;
        capture.author = req.body.author;
        capture.picture = req.body.picture;
        capture.created_at = new Date();


        capture.save(function(err, data){
            if(err)
                throw err;
            console.log(req.body);
            res.json(data);
        });
    });

    router.get('/captures', function(req, res){
        Capture.find({}, function(err, data){
            if(err)
                throw err;
            res.json(data);
        });
    });

     router.delete('/captures', function(req, res){
          Capture.remove({}, function(err){
              res.json({result: err ? 'error' : 'ok'});
          });
      });

    // Map logic to route parameter 'capture'
    router.param('capture', function(req, res, next, id) {
        var query = Capture.findById(id);

        query.exec(function (err, capture) {
            if (err) { return next(err); }
            if (!capture) { return next(new Error("can't find post")); }

            req.capture = capture;
            return next();
        });
    });
    // Map logic to route parameter 'comment'
    router.param('comment', function (req, res, next, id) {
        var query = Comment.findById(id);

        query.exec(function (err, comment) {
            if (err) { return next(err); }
            if (!comment) { return next(new Error("can't find comment")); }

            req.comment = comment;
            return next();
        });
    });  

    router.get('/captures/:id', function(req, res){
         Capture.findOne({_id: req.params.id}, function(err, data){
             if(err)
                throw err;
             res.json(data);
         });
     });

     router.delete('/captures/:id', function(req, res){
         Capture.remove({_id: req.params.id}, function(err){
             res.json({result: err ? 'error' : 'ok'});
         });
     });

    router.post('/captures/:capture/comments', function(req, res, next){
        var comment = new Comment();
        comment.birdname = req.body.birdname;
        comment.body =  req.body.body;
        comment.userId = req.body.userId;
        comment.author = req.body.author;
        comment.created_at = new Date();
        comment.capture = req.capture;

        comment.save(function(err, comment) {
            if (err) { return next(err); }

            req.capture.comments.push(comment);
            req.capture.save(function(err, capture) {
                if (err) { return next(err); }

                res.json(comment);
            });
        });
    });
};