andres
andres

Reputation: 25

Cannot post using express

(UPDATE) I fixed the problem thanks to many people in the comments, now I have a new problem. I can't seem to redirect to the main page after saving the data. I get stuck at an intermidiate HTML that shows me the JSON sentence of what was saved.

I have been trying to use an html form to post information into an API but I always get the error Cannot POST /. I have tried many YouTube tutorials and examples I have seen on GitHub but I just can't seem to make it work. The following is the code that I have been using. Is there anything I'm doing wrong or not seeing ?

this is the server.js (though I don't think the problem is coming from here):

const express = require('express');
const mongoose = require('mongoose');
const app = express();
 
mongoose.connect(process.env.DATABASE_URL, {useNewUrlParser: true, useUnifiedTopology: true })
const db = mongoose.connection
db.on('error', (error) =>  console.error(error))
db.once('open', () => console.log('connected to database'))
 
app.use(express.json())
const jugadorRouter = require('./routes/jugadores')
app.use('/jugadores', jugadorRouter)
 
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));

this is the index where the form is located:

<form name="form" method="post" action="/">
<div class="form-control">
  <label for="username">Usuario</label>
  <input type="text" name="username" id="username" placeholder="Ingrese su usuario..." required />
</div>
<div class="form-control">
  <label for="room">Equipo</label>
  <select name="room" id="room">
    <option value="rojo">Equipo rojo</option>
    <option value="amarillo">Equipo Amarillo</option>
    <option value="blanco">Equipo Blanco</option>
  </select>
</div>
<button id="login" type="submit" class="btn" onclick="javascript: form.action='Gerente.html'" formmethod="post">Gerente</button>                
</form>

This is jugadores.js where the post method is located:

const express = require('express')
const router = express.Router()
const Jugador = require('../model/jugador')
 
router.post('/', async (req, res) => {
 console.log(req.body);
 const jugador = new Jugador({
  username: req.body.username,
  room: req.body.room
})
try{
  const newJugador = await jugador.save()
  res.status(201).json(newJugador)
}catch(err){
  res.status(400).json({message: err.message})
}
res.render('public/Gerente', {
  username: username,
  room: room
});
res.end();
});
 
module.exports = router

This is my jugador.js:

const mongoose = require('mongoose')
//login schema
const jugadorSchema = new mongoose.Schema({
username:{
 type: String,
required: true
},
Date:{
type: Date,
required: true,
default: Date.now
}
})
 
module.exports = mongoose.model('Jugador', jugadorSchema);

Upvotes: 1

Views: 1331

Answers (3)

Aryan
Aryan

Reputation: 3626

Original answer

1. You have specified to use /jugadores before every api route in server.js (app.use('/jugadores', jugadorRouter)) so in Html page your action will look like below

html

 <form name="form" method="post" action="/jugadores/">

and Your api call will look like this http://localhost:3000/jugadores/ if you want use this code the changes will be done in your html form

And

2. If you want use only / in your route than remove /jugadores from app.use('/jugadores', jugadorRouter) so in Html page your action will look like below

html

 <form name="form" method="post" action="/">

server.js

  app.use(jugadorRouter)

and Your api call will look like this http://localhost:3000/ if you want use this code the changes will be done in your server.js file

Update

As mentioned by you in comment that you are getting error

{"message":"Jugador validation failed: username: Path username is required., room: Path room is required."}

To receive POST values in Express, you first need to include the body-parser middleware, which exposes submitted form values on req.body in your route handlers. As mentioned in this tutorial

First install body-parser

in server.js

var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({
    extended: true
}));

Upvotes: 2

vicentedealencar
vicentedealencar

Reputation: 933

As your server is setup, your POST route is /jugadores.

So the form should be:

<form name="form" method="post" action="/jugadores">

And the button should not have onclick or formmethod, like:

<button id="login" type="submit" class="btn">Gerente</button>

Also, so that the server can handle forms add:

app.use(express.urlencoded({extended: true}))

Upvotes: 3

Trang Phạm
Trang Phạm

Reputation: 21

1. What does the error mean?

  • while creating express server, you register a list of route handlers. The error Cannot POST / means express can not find the registration of POST for route /.

2. What is the current situation?

  • after completed, the form submission send the POST request to route /
  • express searchs for its route registration list. It can't find route handle for POST / request. So it yells error

3. How to fix it?

  • when you declare a router handler like this app.use('/jugadores', jugadorRouter), the path of the router handlers will be prefixed with /jugadores. Therefore, the POST / in jugadores.js will actually become POST /jugadores
  • the only route handle express has for now is POST /jugadores. Seems like the form submission should be handled here. So you can change the html form action value like this

<form name="form" method="post" action="/jugadores">

Thanks for the reading!

Upvotes: 2

Related Questions