I was doing youtube clone, during sign up process I got issues with sending data on form-data so my mongoose schema like this:
const { Schema, model } = require("mongoose");
const userSchema = new Schema(
{
username: {
type: String,
required: true,
},
watchHistory: {
type: [
{
video: {
type: Schema.Types.ObjectId,
ref: "video",
},
lastWatchedPosition: {
type: Number,
default: 0,
},
},
],
default: [],
},
likedVideos: {
type: [Schema.Types.ObjectId],
ref: "video",
default: [],
},
email: {
type: String,
},
img: {
filename: String,
contentType: String,
image: Buffer,
},
},
{ timestamps: true, versionKey: false }
);
module.exports = model("user", userSchema);
and server validation part :
const Joi = require("joi");
const paramsSchema = Joi.object({
id: Joi.string().hex().length(24).required(),
});
const watchHistorySchema = Joi.object({
video: Joi.string().hex().length(24).required(),
lastWatchedPosition: Joi.number().default(0),
}).options({ allowUnknown: false });
const bodySchema = Joi.object({
username: Joi.string().min(4).required(),
watchHistory: Joi.array().items(watchHistorySchema),
likedVideos: Joi.array()
.items(Joi.string().hex().length(24).required())
.default([]),
email: Joi.string().email(),
img: Joi.object({
filename: Joi.string().required(),
contentType: Joi.string().required(),
image: Joi.binary().required(),
}),
}).options({ allowUnknown: false });
async function validateParams(req, res, next) {
try {
const validParams = await paramsSchema.validateAsync(req.params);
next(validParams);
} catch (err) {
return res.status(400).send({ msg: err.message });
}
}
async function validateBody(req, res, next) {
console.log(req.body); // output - {}
try {
const validParams = await bodySchema.validateAsync(req.body);
next(validParams);
} catch (err) {
return res.status(400).send({ msg: err.message });
}
}
module.exports = { validateParams, validateBody };
routes part :
const router = require("express").Router();
const { getAll, getOne, editOne, deleteOne } = require("../controllers/user");
const { signup, login } = require('../utils/auth')
const { validateParams, validateBody } = require('../validations/user')
const multer = require("multer");
const storage = multer.memoryStorage();
const upload = multer({ storage });
router.route("/signup").post( validateBody, upload.single('img'), signup);
router.route("/").get(getAll);
router.route("/:id").get(validateParams, getOne);
router.route("/:id").patch(validateParams, editOne);
router.route("/:id").delete(validateParams, deleteOne);
module.exports = router;
and finally index.js
const expr = require("express");
const app = expr();
const { config } = require("dotenv");
const session = require("express-session");
const DB = require("./settings/DB/db");
const allRoutes = require("./router");
const bodyParser = require("body-parser");
config();
DB();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded())
// app.use(expr.json())
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
})
);
app.use("/api", allRoutes);
// Global error handler middleware
app.use((err, req, res, next) => {
if (err) {
console.log(err, "-err");
res.status(500).json({ message: `Internal Server Error` });
}
next();
});
app.listen(process.env.PORT, () => {
console.log(`${process.env.PORT}'s port online...`);
});
postman screenshot
when I remove validation from routes it’s working fine, also checked validation, and all things fine.
Main problem’s working with form-data.