Home > Software engineering >  I'm having trouble calling the correct data for my post-form
I'm having trouble calling the correct data for my post-form

Time:03-15

Im trying to create a comment function so that I can review products. I've gotten it to work in the back-end and I've tested the function through postman. But when I try to post via the form on the ejs, it fails the null constraints. I understand that my ejs tags are not provided with the correct data but I dont know how to solve the problem.

product-routes.js

/***********************************************************/

//get product by id
router.get('/product/:id', (req, res) => {
    const id = req.params.id;
    Product.findById(id).populate('reviews')
        .then(result => {
            res.render('product-details', { title: 'product details', product: result });
        })
        .catch(err => {
            res.status(404).render('404', { title: '404' }); //renders the 404 page if product with id does not exist
            console.log(err);
        });
});

/***********************************************************/

//post review on post
router.post('/product/:id/review', (req, res) => {
    const id = req.params.id;
    const review = new Review(req.body);
    //const currentUser = req.user;
    review //create a new review
        .save()
        .then(() => Product.findById(id)) //find the product that is being reviewed
        .then((result) => {
            result.reviews.unshift(review); //append review details to this product, unshift puts the newest entry at the top
            return result.save();
        })
        .then(() => res.redirect('back'))
        .catch((err) => {
            console.log(err);
        });
});

/***********************************************************/

review-model.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

//schema for the review table in the mongoDB
const reviewSchema = new Schema({
    comment: {
        type: String,
        required: true
    },
    rating: {
        type: Number,
        required: true,
        enum: [1, 2, 3, 4, 5]
    },
    date: {
        type: Date,
        required: true,
        default: Date.now
    },
});

const Review = mongoose.model('Review', reviewSchema);

module.exports = Review;

product-details.ejs

                <!-- looping through all our comments to show them in the table -->
                <div >
                    <table >
                        <thead>

                            <tr>
                                <th scope="col">Comment</th>
                                <th scope="col">Rating</th>
                                <th scope="col">Date</th>
                                <th scope="col">Posted by:</th>

                            </tr>
                        </thead>

                        <tbody id="table-body">
                            <% product.reviews.forEach(review=> { %>
                                <tr>
                                    <td>
                                        <p>
                                            <%= review.comment %>
                                        </p>
                                    </td>
                                    <td>
                                        <p>
                                            <%= review.rating %>/5
                                        </p>
                                    </td>
                                    <td>
                                        <p>
                                            <%= review.date %>
                                        </p>
                                    </td>
                                    <td>
                                        <p>placeholder</p>
                                    </td>
                                </tr>

                                <% }) %>
                        </tbody>
                    </table>
                </div>

                <form action="/shop/product/<%= product._id %>/review" method="POST">
                    <textarea name="reviews[comment]" required></textarea>
                    <input type="number" name="reviews[rating]" min="1" max="5" step="1" required>
                
                    <input type="submit">
                </form>   

product-model.js (just in case)

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

//add comment
const productSchema = new Schema({
    title: {
        type: String,
        required: true
    },
    gender: {
        type: String,
        required: true
    },
    brand: {
        type: String,
        required: true
    },
    size: {
        type:String,
        required: true
    },
    picture: {
        type: String,
        required: true
    },
    description: {
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true
    },
    //foreign key to retrieve an array of reviews on the product
    reviews: [{
        type: Schema.Types.ObjectId, 
        ref: 'Review'
    }]
}, {timestamps: true });

const Product = mongoose.model('Product', productSchema);

module.exports = Product;

Error output:

Error: Review validation failed: rating: Path `rating` is required., comment: Path `comment` is required.
    at ValidationError.inspect (C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\error\validation.js:48:26)
    at formatValue (node:internal/util/inspect:780:19)
    at inspect (node:internal/util/inspect:345:10)
    at formatWithOptionsInternal (node:internal/util/inspect:2165:40)
    at formatWithOptions (node:internal/util/inspect:2027:10)
    at console.value (node:internal/console/constructor:324:14)
    at console.log (node:internal/console/constructor:360:61)
    at C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\routes\product-routes.js:114:21
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  errors: {
    rating: ValidatorError: Path `rating` is required.
        at validate (C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\schematype.js:1322:13)
        at C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\schematype.js:1305:7
        at Array.forEach (<anonymous>)
        at SchemaNumber.SchemaType.doValidate (C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\schematype.js:1255:14)
        at C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\document.js:2745:18
        at processTicksAndRejections (node:internal/process/task_queues:78:11) {
      properties: [Object],
      kind: 'required',
      path: 'rating',
      value: undefined,
      reason: undefined,
      [Symbol(mongoose:validatorError)]: true
    },
    comment: ValidatorError: Path `comment` is required.
        at validate (C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\schematype.js:1322:13)
        at C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\schematype.js:1305:7
        at Array.forEach (<anonymous>)
        at SchemaString.SchemaType.doValidate (C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\schematype.js:1255:14)
        at C:\Users\Karwan Gara\Studier\År 3\GIK2PG (Projektbaserad systemutveckling)\Latest working\Sneakers-Ecommerce-Website\node_modules\mongoose\lib\document.js:2745:18
        at processTicksAndRejections (node:internal/process/task_queues:78:11) {
      properties: [Object],
      kind: 'required',
      path: 'comment',
    at runMicrotasks (<anonymous>)

CodePudding user response:

You need to use use app.use(express.urlencoded({ extended: true }));

CodePudding user response:

Try changing the form input names. from name="reviews[comment]" to name="comment" and from name="reviews[rating]" to name="rating"

  • Related