Grizzly Bear
Grizzly Bear

Reputation: 338

Cast to ObjectId failed for value at path for model error

This is my Profile Schema:

const mongoose = require('mongoose');

const ProfileSchema = new mongoose.Schema({
    user: {
        // Special field type because
        // it will be associated to different user
        type: mongoose.Schema.Types.ObjectId,
        ref: 'user',
    },
    company: {
        type: String,
    },
    website: {
        type: String,
    },
    location: {
        type: String,
    },
    status: {
        type: String,
        required: true,
    },
    skills: {
        type: [String],
        required: true,
    },
    bio: {
        type: String,
    },
    githubusername: {
        type: String,
    },
    experience: [
        {
            title: {
                type: String,
                required: true,
            },
            company: {
                type: String,
                required: true,
            },
            location: {
                type: String,
            },
            from: {
                type: Date,
                required: true,
            },
            to: {
                type: Date,
            },
            current: {
                type: Boolean,
                default: false,
            },
            description: {
                type: String,
            },
        },
    ],
    education: [
        {
            school: {
                type: String,
                required: true,
            },
            degree: {
                type: String,
                required: true,
            },
            fieldofstudy: {
                type: String,
                required: true,
            },
            from: {
                type: Date,
                required: true,
            },
            to: {
                type: Date,
            },
            current: {
                type: Boolean,
                default: false,
            },
            description: {
                type: String,
            },
        },
    ],
    social: {
        youtube: {
            type: String,
        },
        twitter: {
            type: String,
        },
        facebook: {
            type: String,
        },
        linkedin: {
            type: String,
        },
        instagram: {
            type: String,
        },
    },
    date: {
        type: Date,
        default: Date.now,
    },
});

module.exports = Profile = mongoose.model('profile', ProfileSchema);

   

This is my view api. It doesn't work. it only return Cast to ObjectId failed for value { 'experience._id': '5edcb6933c0bb75b3c90a263' } at path _id for model profile

router.get('/experience/viewing/:viewexp_id', auth, async (req, res) => {
    try {
        const exp = await Profile.findById({
            'experience._id': req.params.viewexp_id,
        });

        if (!exp) {
            return res.status(404).json({ msg: 'Experience not found' });
        }

        res.json(exp);
    } catch (err) {
        console.error(err.message);
        res.status(500).send(err.message);
    }
});

How can I fix this? I tried looking at the stackoverflow of the same errors. still it doesn't seem to work.

and this is what I am trying to hit

Mongodb experience Screenshot

Upvotes: 1

Views: 6148

Answers (3)

Bhojak Rahul
Bhojak Rahul

Reputation: 31

router.post(
  "/",
  [
    auth,
    [
      check("status", "status is required").not().isEmpty(),
      check("skills", "skills is required").not().isEmpty(),
    ],
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const {
      company,
      website,
      location,
      bio,
      status,
      githubuername,
      skills,
      youtube,
      facebook,
      twitter,
      instagram,
      linkedin,
    } = req.body;

    const profileFileds = {};
    profileFileds.user = req.user.id;
    if (company) profileFileds.company = company;
    if (website) profileFileds.website = website;
    if (location) profileFileds.location = location;
    if (bio) profileFileds.bio = bio;
    if (status) profileFileds.status = status;
    if (githubuername) profileFileds.githubuername = githubuername;
    if (skills) {
      profileFileds.skills = skills.split(",").map((skill) => skill.trim());
    }

    //Build profile object
    profileFileds.social = {};

    if (youtube) profileFileds.social.youtube = youtube;
    if (twitter) profileFileds.social.twitter = twitter;
    if (facebook) profileFileds.social.facebook = facebook;
    if (linkedin) profileFileds.social.linkedin = linkedin;
    if (instagram) profileFileds.social.instagram = instagram;

    try {
      let profile = await Profile.findOne({ user: req.user.id });

      if (profile) {
        //update
        profile = await Profile.findOneAndUpdate(
          { user: req.user.id },
          { $set: profileFileds },
          { new: true }
        );
        return res.json(profile);
      }

      //Create profile
      profile = new Profile(profileFileds);
      await profile.save();
      res.json(profile);
    } catch (err) {
      console.error(err.message);
      res.status(500).send("server Error");
    }
  }
);

Upvotes: 0

turivishal
turivishal

Reputation: 36114

The problem is that you have to convert your string _id to mongoose object id using this function mongoose.Types.ObjectId and my suggestion is to use findOne function instead of findById,

var mongoose = require('mongoose');

router.get('/experience/viewing/:viewexp_id', auth, async (req, res) => {
    
    try {

        let id = mongoose.Types.ObjectId(req.params.viewexp_id);
        
        const exp = await Profile.findOne(
            { "experience._id": req.params.viewexp_id }, 
            // This will show your sub record only and exclude parent _id
            { "experience.$": 1, "_id": 0 }
        );

        if (!exp) {
            return res.status(404).json({ msg: 'Experience not found' });
        }

        res.json(exp);

    } catch (err) {
        console.error(err.message);
        res.status(500).send(err.message);
    }

});

Upvotes: 2

Kuldeep Mishra
Kuldeep Mishra

Reputation: 4040

var mongoose = require('mongoose');

router.get('/experience/viewing/:viewexp_id', auth, async (req, res) => {
try {
    const exp = await Profile.findOne({
        'experience._id': mongoose.Types.ObjectId(req.params.viewexp_id),
    });

    if (!exp) {
        return res.status(404).json({ msg: 'Experience not found' });
    }

    res.json(exp);
} catch (err) {
    console.error(err.message);
    res.status(500).send(err.message);
}
});

You are saving object id . but your param id is string. convert it in ObjectId. Please check my solution.

Upvotes: 1

Related Questions