Error: 'name' is required. on post request from postman using form data

Viewed 684

error picture of postman .required() function is used for name, price, quantity in post request from node js. if i remove required function then it works correctly. Code of model file:

var productSchema = mongoose.Schema({
  name: String,
  price: Number,
  quantity: Number,
});
var Product = mongoose.model("Product", productSchema);

function validateProduct(data) {
  const schema = Joi.object({
    name: Joi.string().min(3).required(),
    price: Joi.number().min(0).required(),
    quantity: Joi.number().min(0).required(),
  });

Code of api file

router.post(
      "/",
      validateProduct,
      upload.single("productImage"),
      async (req, res) => {
        console.log(req.file);
        let product = await Product.findOne({ name: req.body.name });
        if (product)
          return res.status(400).send("Product with same name already exist!");
        product = new Product();
        product.name = req.body.name;
        product.price = req.body.price;
        product.quantity = req.body.quantity;
        await product.save();
        return res.send(product);
      }
    );
1 Answers

I saw a few problems :

  • Firstly, you're using validateProduct as middleware in POST "/" route. So, the function should have (req, res, next) as parameters. I'm not sure why it can work when you remove the required function in the JOI schema. In my test, I rewrite it as :
function validateProduct(req, res, next) {
     
    // to check the value of req.body
    console.log(req.body);

     // create schema object
    const schema = Joi.object({
        name: Joi.string().min(3).required(),
        price: Joi.number().min(0).required(),
        quantity: Joi.number().min(0).required(),
    }).required();

    // schema options
    const options = {
        abortEarly: false, // include all errors
        allowUnknown: true, // ignore unknown props
        stripUnknown: true // remove unknown props
    };

    // validate request body against schema
    const { error, value } = schema.validate(req.body, options);

    if (error) {
        // on validate failed
        req.validationError = true;
        next();
    } else {
        // on success replace req.body with validated value and trigger next middleware function
        req.body = value;
        next();
    }
}
  • Secondly, the req.body isn't fully populated before calling the upload middleware. You need to put the validateProduct middleware after upload. (I added console.log(body) in the validateProduct function above, you can see the difference in the 2 cases.)
app.post(
    "/",
    upload.single("productImage"),
    validateProduct,
    async (req, res) => {
        console.log(req.file);

        if (req.validationError) {
            // validation failed
            fs.unlinkSync(req.file.path); // need require("fs") at the top of file
            return res.status(400).send("Parameters is not valid!");
        }


        let product = await Product.findOne({ name: req.body.name });
        if (product) {
            return res.status(400).send("Product with same name already exist!");
        }
        product = new Product();
        product.name = req.body.name;
        product.price = req.body.price;
        product.quantity = req.body.quantity;
        await product.save();
        return res.send(product);
    }
);
  • Finally (optional), because we already upload the file before validating the other fields, we need to remove the file if the requirements are not met.
Related