Reputation: 1831
I'm trying to pass form data from login page to signin page via post using fetch with this pug code:
form(id="form-login")
input(type="text", name="email", value="", placeholder="Tu email")
br
input(type="password", name="password", value="", placeholder="Tu contraseña")
br
input(type="submit" value="Conectar")
script.
const formLogin = document.querySelector('#form-login');
const formData = new FormData(formLogin);
formLogin.addEventListener('submit', function(event) {
console.log('Form Data: ', formData);
event.preventDefault();
fetch('/signin', {
method: 'POST',
body: formData
})
.then(function(res) {
res.json();
})
.then(function(data) {
console.log(data)
localStorage.setItem('token', data.token)
})
});
The problem is an empty req.body reaching to signin.. After trace it gives this console.log
Form Data: FormData {}
and also an undefined req.body.
If I comment this script and just send it through form adding action="/signin" and method="post"
, it works and the answer is printed, but calling storage.setItem({ token: <token> })
returns an Uncaught (in promise) TypeError: Cannot read property 'token' of undefined
I'm wondering why this script is not sending the data... can't figure out... so any help will be much apreciated.
Signin function:
function signIn (req, res) {
if (!req.body.email) return res.status(200).send({message: 'No recibo el usuario'})
User.findOne({ email: req.body.email }, (err, user) => {
if(err) return res.status(500).send({ message: err })
if(!user) return res.status(404).render('login', { title: 'Intenta loguearte de nuevo' })
user.comparePassword(req.body.password, (error, isMatch) => {
if (error) return res.status(500).send({ message: error })
if (!isMatch) {
return res.redirect('login')
} else {
req.user = user
res.status(200).send({
message: 'Te has logueado correctamente',
token: service.createToken(user)
})
//$window.localStorage.setItem({token: service.createToken(user)}); // NO WORKS
return res.body = service.createToken(user) // TRYING THIS WITHOUT KNOWLEDGE ABOUT WHAT AM I DOING :O
}
})
})
}
Thanks in advance.
****EDIT****
As @MichałSałaciński suggest, commenting first .then res.json()....
At least gives a response, but still don't undestand what's hapenning here and in order to learn properly and make things better, also hope someone can explain how to correctly do stuff like this.
Response: body : ReadableStream
locked : false
__proto__ : Object
bodyUsed : false
headers : Headers
__proto__ : Headers
ok : true
redirected : false
status : 200
statusText: "OK"
type : "basic"
Upvotes: 4
Views: 2635
Reputation: 146
So I was having the same issue where the POST request from my pug form was sending back an empty {}
as the req.body
object. The code was a simple create action using these:
bookController.js
exports.createBookForm = (req,res) => {
res.render("create_book_form", { title: "Add A New Book"})
}
exports.createBook = (req,res) => {
const reqFields = ["title", "author"];
for (let i = 0; i < reqFields.length; i++) {
const field = reqFields[i];
if (!field in req.body) {
const message = `Missing ${field} in the request body`;
console.log(message)
return res.status(400).send(message)
}
}
Book
.create({
title: req.body.title,
author: req.body.author,
summary: req.body.summary
})
.then((book) => {
res.status(201).json(book.serialize())
})
.catch(err => {
console.log(err);
})
}
And the create book form:
block content
h1 Add a Book
h3 Do use real details. Otherwise, what's the point?
form(method="POST" action="/books")
div.form-group
label(for="title") Title:
input#title.form-control(type="text", placeholder="Small Gods" name="title")
label(for="author") Author:
input#author.form-control(type="text", placeholder="Terry Pratchett" name="author")
label(for="summary") Summary:
textarea#summary.form-control(type="text", placeholder="God is turtle, world is flat" name="summary")
div.form-group
button.btn.btn-primary(type="submit" role="submit") Add Book
What finally fixed getting the actual req.body to show up for the POST action was adding (within server.js)
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
Let me know if this works for you. Took me a couple hours to come to this conclusion and I hate seeing questions go unanswered.
Upvotes: 4
Reputation: 2266
You should move "new FormData" inside "send" event listener. Also, there's missing comma after type="submit", but overall, the problem got nothing to do with pug :)
form(id="form-login")
input(type="text", name="email", value="", placeholder="Tu email")
br
input(type="password", name="password", value="", placeholder="Tu contraseña")
br
input(type="submit",value="Conectar")
script.
const formLogin = document.querySelector('#form-login');
formLogin.addEventListener('submit', function(event) {
const formData = new FormData(formLogin);
console.log('Form Data: ', formData);
event.preventDefault();
fetch('/signin', {
method: 'POST',
body: formData
})
.then(function(res) {
res.json();
})
.then(function(data) {
console.log(data)
localStorage.setItem('token', data.token)
})
});
Upvotes: 0