How to Update Multiple Fields Inside an Array in Mongodb, Express, NodeJs?

Viewed 1357

How to Update Multiple Objects by Its ID inside an array? I wanted to Update the experience by its ID by the User,

Below i have attached my mongodb json object screenshot:

Image

I can already Create an Experience by the User:

router.put('/experience',
    [
        auth,
        [
            check('title', 'Title is required').not().isEmpty(),
            check('company', 'Company is required').not().isEmpty(),
            check('from', 'From date is required').not().isEmpty(),
        ],
    ],
    async (req, res) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }

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

        const newExp = {
            title,
            company,
            location,
            from,
            to,
            current,
            description,
        };

        try {
            const profile = await Profile.findOne({ user: req.user.id });
            // unshift is same with push it pushes it in the beginner rather than the end
            profile.experience.unshift(newExp);

            await profile.save();

            res.json(profile);
            console.log(req.body);
        } catch (err) {
            console.error(err.message);
            res.status(500).send('Send Error');
        }
    }
);

and Here is my non working code about the Update strong text

router.patch('/experience/:exp_id', auth, async (req, res) => {
    let id = req.params.exp_id;
    let expId = req.body;
    try {
        const profile = await Profile.findOne({ user: req.user.id });

        profile.experience.findOneAndUpdate(
            { id },
            { $set: { expId } },
            { new: true }
        );
        res.json(profile);
    } catch (err) {
        console.error(err.message);
        res.status(500).send(err.message);
    }
});
2 Answers

Look around this, corrected below things:

  1. from { id } to { "experience._id": id }
  2. { $set: { expId } } to { $set: { fields of experience } }
  3. removed const profile = await Profile.findOne({ user: req.user.id });
  4. from profile.experience.findOneAndUpdate to Profile.findOneAndUpdate
  5. added data and error response function (err, data)
router.patch('/experience/:exp_id', auth, async (req, res) => {
    let id = req.params.exp_id;
    let expId = req.body;
    try {
        await Profile.findOneAndUpdate(
            { 
                "experience._id": id
            },
            { 
                $set: { 
                    'experience.$.title': req.body.title, 
                    'experience.$.company': req.body.company, 
                    'experience.$.from': req.body.from, 
                }
            },
            { new: true },
            (err, data) => {
                if (!err){
                    res.json(data);
                }else{
                    res.json(err);
                }
            }
        );
    } catch (err) {
        console.error(err.message);
        res.status(500).send(err.message);
    }
});

Hope this will help you.

https://stackoverflow.com/a/47762417/13199635 This should help you out. Also in your current code, where you are updating your profile.experience, you should probably use {_id: id} instead of just {id}. so your updated code would be like

profile.experience.findOneAndUpdate(
            { _id: id },
            { $set: { expId } },
            { new: true }
        );
        res.json(profile);

Hope this helps

Related