Submitting an empty {} after the "post" form with pug in node.js

I'm trying to pass form data from login page to signed page via post using fetch with this 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 the empty req.body command available for input. After tracing, it gives this console.log

Form Data:  FormData {}

      

and also undefined req.body. If I comment out this script and just submit it via form add action="/signin" and method="post"

it works and the response is printed, but the call storage.setItem({ token: <token> })

returns Uncaught (in promise) TypeError: Cannot read property 'token' of undefined

I am wondering why this script is not submitting data ... cannot figure it out ... so any help would be greatly appreciated ...

Login 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 said, commenting first .then res.json()....

At least gives an answer, but still don't get discouraged with what is happening here, and in order to learn correctly and improve the situation, I also hope someone- it can explain how to do things like this correctly.

  Response: body : ReadableStream
locked : false
__proto__ : Object
bodyUsed :   false
headers :  Headers
__proto__  :  Headers
ok :  true
redirected :  false
status : 200
statusText: "OK"
type  :   "basic"

      

+3


source to share


2 answers


So I had the same issue where the POST request from my rogue form was submitting empty {}

as an object req.body

. The code was a simple step to create using the following:

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 create a book shape:



block content
  h1 Add a Book
  h3 Do use real details. Otherwise, what 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 display for the POST action was the addition (in server.js)

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

      

Let me know if this works for you. It took me a couple of hours to come to this conclusion, and I hate that questions go unanswered.

+1


source


You must move the "new FormData" inside the "send" event listener. Also, there is no comma after type = "submit", but overall the problem has nothing to do with the 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)
        })
    });

      

0


source







All Articles