0

When I console.log the req.body it gives me:

[Object: null prototype] {
  'shoe[name]': 'Shoe Name',
  'shoe[description]': '',
  'shoe[pictures]': '',
  'shoe[collections]': 'Shoe Collection'
}

But when I console.log req.body.shoe It prints undefined, been breaking my head for a few days now

The form:

<form action="/shoes/" method="post">
  <input type="text" name="shoe[name]" placeholder="Name of the shoe">
  <textarea name="shoe[description]" cols="30" rows="10"></textarea>
  <input type="file" name="shoe[pictures]">
  <input type="text" name="shoe[collections]">
  <input type="submit" value="Post the Shoe">
</form>

Shoe Model:

const mongoose = require('mongoose');

const shoeSchema = new mongoose.Schema({
    name: { type: String, unique: true },
    description: String,
    displayPicture: mongoose.Schema.Types.ObjectId,
    pictures: [ { type: mongoose.Schema.Types.ObjectId } ],
    collections: [ { type: mongoose.Schema.Types.ObjectId, unique: true } ],
    dateOfPublish: { type: Date, default: Date.now },
    comments: [
        {
            userId: { type: mongoose.Schema.Types.ObjectId, unique: true, ref: 'Comment' }
        }
    ]
});

module.exports = mongoose.model('Shoe', shoeSchema);

Node.js + Express create route:

//Create
router.post('/', (req, res) => {
    console.log(req.body.shoe);
    Shoe.create(req.body.shoe, (err, shoe) => {
        if (err) {
            console.log(err);
        } else {
            return res.redirect('/');
        }
    });
});
Dominik
  • 6,078
  • 8
  • 37
  • 61
i5x
  • 15
  • 3

3 Answers3

0

You cannot implement the below way the html part <input type="file" name="shoe[pictures]"> You yourself is seeing that

 [Object: null prototype] {
  'shoe[name]': 'Shoe Name',
  'shoe[description]': '',
  'shoe[pictures]': '',
  'shoe[collections]': 'Shoe Collection'
}

'shoe[pictures]' is the entire key and you are only accessing req.body.shoe

First your entire HTML need to be changed.

        <form action="/shoes/" method="post">
            <input type="text" name="name" placeholder="Name of the shoe">
            <textarea name="description" cols="30" rows="10"></textarea>
            <input type="file" name="pictures">
            <input type="text" name="collections">
            <input type="submit" value="Post the Shoe">
        </form>

And then in backend in req.body object you will receive all the properties name,description,pictures,collections

After that you can access req.body.name req.body.description etc

Then in backend you need to define var shoe = {...req.body} and then you can use shoe object

Sunil Choudhary
  • 329
  • 1
  • 6
  • It is possible and that's exactly what confuses me, refer to this post: https://stackoverflow.com/questions/40162911/js-object-notation-in-html-input-name – i5x Sep 10 '20 at 09:59
  • It will not work for node js. He might have that formulae for some other language. Please dont follow that – Sunil Choudhary Sep 10 '20 at 13:55
  • The thing is it did work on my previous Udemy project I finished recently (using node, same version), so there is no reason not to since it shortens the code. [see in create route](https://github.com/lucasweng/yelp-camp/blob/master/routes/comments.js) My structure here is very similar but it doesn't want to work for some reason – i5x Sep 10 '20 at 16:49
  • First of all it works because it uses ejs code to render html. The same repository that you showed in previous ```https://github.com/lucasweng/yelp-camp/blob/master/routes/comments.js``` code just go to ```show.ejs``` ```file``` you will understand how it was implemented. It does shorten the code but it also renders from server. So no matter what you it wont work unless you do using server side rendering – Sunil Choudhary Sep 10 '20 at 17:54
  • This project also uses server-side, same as that one with the same dependencies – i5x Sep 10 '20 at 18:10
  • It doesnt matter if the project uses the server code or not. it matters if the HTML Form code which you use is rendered by server side code or not. In above example you have used plain HTML and javascript code. But the code that you have asked to take reference from [link](https://github.com/lucasweng/yelp-camp/blob/master/views/users/show.ejs) is itself using ejs server side rendering of HTML Form tag with all of format that you want to use. I hope now you get it. – Sunil Choudhary Sep 10 '20 at 18:17
  • Oh yhea, the filetype of the form is ejs, rendering is done with ```res.render('shoes/new.ejs')```. As I've said, same structure and dependencies for both of these projects. Here is a [link](https://github.com/i5x64BIT/onlineshoestore) to the project, would be happy if you could spot the issue there – i5x Sep 10 '20 at 18:48
0
<% include ../partials/header %>
  <div class="row">
    <div class="col-md-4">
      <h2><%= user.firstName + " " + user.lastName %></h2>
      <div class="thumbnail">
        <img src="<%= user.avatar %>" alt="user profile image">
        <div class="caption"><a href="mailto:<%= user.email %>"><%= user.email %></a></div>
      </div>
    </div>
    <div class="col-md-8">
    ``` <h3><%= user.username %>'s campgrounds</h3>
        <% campgrounds.forEach(campground => { %>
          <div class="col-md-4 col-sm-6">
            <div class="thumbnail card">
              <img src="<%= campground.image.url %>" alt="<%= campground.name %>">
              <div class="caption">
                <h4 class="caption"><a href="/campgrounds/<%= campground.id %>"><%= campground.name %></a></h4>
              </div>
            </div>
          </div>
        <% }); %>
      </ul>
    </div>
    <a href="/users/<%= user._id%>/edit">Edit Profile</a>
  </div>
<% include ../partials/footer %>

Can you see that %include is written here. if that statement is not present in your code it will not work. That is what i am trying to explain from that time

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>New Shoe</title>
</head>
<body>
    <form action="/shoes/" method="post">
        <input type="text" name="shoe[name]" placeholder="Name of the shoe">
        <textarea name="shoe[description]" cols="30" rows="10"></textarea>
        <input type="file" name="shoe[pictures]" value="Shoe Pictures">
        <!-- tick the display pic -->
        <input type="text" name="shoe[collections]">
        <input type="submit" value="Post the Shoe">
    </form>
</body>
</html>

In your there is nothing like that

Sunil Choudhary
  • 329
  • 1
  • 6
0

The problem was with the body-parser, needed to use the qs library (true) instead of querystring(false) in the following line:

app.use(require('body-parser').urlencoded({ extended: true }));

originally extended was set to false. for more info refer to this link

i5x
  • 15
  • 3