Search code examples
javascriptnode.jsexpressmongoosepug

Express.js POST method doesn't work


I'm trying to make a discussion-based Node.js/Express-app and I'm working on the page to create a discussion. I was just testing if my discussion controller file was linked, but everytime I click the button to POST my form, it doesn't do anything.

my pug (view), called 'createDisc.pug'

extends layout
block content
    h1 Create new discussion
    form(action='', method='post')
    div
        label(for='title') Title
        input#title
    div
        label(for='desc') Description
        input#desc
    div
        input(type='submit', value='Create')

my router, called 'createDisc.js'

var express = require('express');
var router = express.Router();
var disc = require('../controllers/disc');

router.get('/discussion/create', function (req, res, next) {
    res.render('createDisc');
});

router.post('/discussion/create', disc.createDisc);

module.exports = router;

my controller called 'disc.js' where I'm just trying to send 'test' to my console

exports.createDisc = function (req, res, next) {
    console.log('test');
};

my app.js file

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const passport = require('passport');
const path = require('path');
const cookieParser = require('cookie-parser');
const session = require('express-session');

const app = express();

const db = require('./controllers/db');

require('./config/passport')(passport);

mongoose.connect(db.url);

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());
app.use('/', require('./routes/createDisc'));

app.listen(3000, function() {
    console.log('Example listening on port 3000!')
})

Solution

  • You mentioned /discussion/create as your GET route and linking it to the express router like:

    router.get('/discussion/create', function (req, res, next) {
        res.render('createDisc');
    });
    
    router.route('/discussion/create', disc.createDisc);
    

    So in reality, you are enabling the route something like:

    GET /discussion/create/discussion/create

    Please try with .post() hook and use it like:

    router.post('/', function (req, res, next) {
        res.render('createDisc');
    });
    
    router.route('/discussion', disc.createDisc);
    

    Reference: http://expressjs.com/en/guide/routing.html

    Tip: Please refer to this link for making more meaningful routes. https://github.com/squareboat/api-guidelines#http-methods

    Update #1

    Currently, in your HTML(pug) form, you have action='', this means your form is making request to POST /.

    Please change the action value to action='/discussion/create' and try again.

    Update #2

    I have made a trimmed down version of your code(without view or db), and it's working perfectly. you can see code here.

    Routes to test are:

    GET http://localhost:3000/discussion/create
    
    POST http://localhost:3000/discussion/create
    

    Update #3

    In your pug file, your indentation is wrong because of which the input fields are not enclosed inside the form tag. You had an empty form.

    extends layout
    block content
        h1 Create new discussion
            form(action='/discussion/create', method='post')
                div
                    label(for='title') Title
                    input#title
                div
                    label(for='desc') Description
                    input#desc
                div
                    input(type='submit', value='Create')
    

    This will work.