node.jsmongodbvalidationmongoosepostman

Getting Validation Failed: Path is required Error even when I am providing all the required data


I am using Mongoose in my Nodejs application and I want to create a new Experience collection. For that I am providing all the data in Postman. I am using application/x-www-form-urlencoded to send my data. But I keep Getting the error

"Experience validation failed: experience.from: Path experience.from is required., experience.company: Path experience.company is required., experience.title: Path experience.title is required."

again and again. I have checked my Schema and my code for any spell mistakes but I don't seem to find any. I have checked this error on many sites but the answer always seems to be either spell mistakes or "requires should be set to false in Schema". But I have put required to true because I need that.

Here is my Schema

import mongoose from "mongoose";

const experienceSchema = new mongoose.Schema({
    experience: {
        user: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User",
        },
        title: {
            type: String,
            required: true,
        },
        company: {
            type: String,
            required: true,
        },
        location: String,
        from: {
            type: Date,
            required: true,
        },
        to: {
            type: Date,
        },
        current: {
            type: Boolean,
            default: false,
        },
        description: String,
    },
});

const Experience = mongoose.model("Experience", experienceSchema);

export default Experience;

Here is my Route file for Experience

import express from "express";
import Profile from "../models/Profile.js";
import Experience from "../models/Experience.js";
import auth from "../middleware/auth.js";
import { body, validationResult } from "express-validator";

const router = express.Router();

// Create Experience
// Endpoint experience/
router.post(
    "/",
    auth,
    body("title", "Please provide your title").notEmpty().trim(),
    body("company", "Please provide your company name").notEmpty().trim(),
    body("location").trim(),
    body("from", "From date is required").notEmpty().trim(),
    body("to").trim(),
    body("current").isBoolean(),
    body("description").trim(),
    async (req, res) => {
        let profile = await Profile.findOne({ user: req.userid });
        if (!profile) {
            return res
                .status(400)
                .send("Profile does not exist! Please create a Profile.");
        }

        const result = validationResult(req);

        if (!result.isEmpty()) {
            return res.status(400).json({ errors: result.array() });
        }

        const { title, company, location, from, to, current, description } =
            req.body;

        try {
            const experienceFields = new Experience({
                title,
                company,
                location,
                from,
                to,
                current,
                description,
            });

            await experienceFields.save();

            return res.json(experienceFields);
        } catch (error) {
            console.error(error.message);
            res.status(500).send("Server Error...");
        }
    }
);

Here's my index.js file

import express from "express";
import connectDB from "./db.js";
import user from "./routes/user.js";
import auth from "./routes/auth.js";
import profile from "./routes/profile.js";
import experience from "./routes/experience.js";

const app = express();
const port = 3000;

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.use("/user", user);
app.use("/auth", auth);
app.use("/profile", profile);
app.use("/experience", experience);

app.listen(port, () => {
    console.log(`Listening on port ${port}`);
});

connectDB();

Here is an image of my data in Postman enter image description here

I tried sending data as raw json and using json() parser as middleware but it keeps giving the same error.


Solution

  • Your schema has the wrong structure. The experience model has one field experience structured as an object with fields user, title, etc., so your experience object looks like this:

    {
        "experience": {
            "user": {...},
            "title": "example title",
            "company": "example company"
            ...
        }
    }
    

    instead of:

    {
        "user": {...},
        "title": "example title",
        "company": "example company"
        ...
    }
    

    You should "flatten" the schema to remove the wrapping experience object:

    const experienceSchema = new mongoose.Schema({
        user: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User",
        },
        title: {
            type: String,
            required: true,
        },
        company: {
            type: String,
            required: true,
        },
        location: String,
        from: {
            type: Date,
            required: true,
        },
        to: {
            type: Date,
        },
        current: {
            type: Boolean,
            default: false,
        },
        description: String,
    });
    
    const Experience = mongoose.model("Experience", experienceSchema);
    
    export default Experience;