ReactJS + Axios + NodeJS - _id: Cannot read property 'ownerDocument' of null

Viewed 1398

I have this ReactJS app connected by Axios to a backend in Node. I'm trying to update, and the payload is correct, but I have an awkward problem: it says I'm not sending the _id that I need to be updated. Here is my mongoose Schema, the request in Axios and the express backend method for it.

Axios request:

    submit () {
    let data = this.state.category
    axios({
        method: this.state.category._id ? 'put':'post',
        url: `/category/${this.state.category._id || ''}`,
        data: data
    })
    .then(res => {
        let list = this.state.categoryList
        list.push(res.data.category)
        this.update({
            alert: {
                type: "success",
                text: "Category updated"
            },
            categoryList: list
        })
      this.toggleLarge()
    })
    .catch(e => {
        this.update({
            category: {
                errors: e.errors
            },
            alert: {
                type: "danger",
                text: "Error",
                details: e
            }
        })
    })
}

Mongoose Schema:

const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');

let Schema = mongoose.Schema;

let categorySchema = new Schema({
    description: {
        type: String,
        unique: true,
        required: [true, 'Category required']
    }
});

categorySchema.methods.toJSON = function() {

    let category = this;
    let categoryObject = category.toObject();

    return categoryObject;
}

categorySchema.plugin(uniqueValidator, { message: '{PATH} must be unique' });

module.exports = mongoose.model('Category', categorySchema);

Express method:

 app.put('/category/:id', [verifyToken], (req, res) => {
    let id = req.params.id;

    Category.findByIdAndUpdate(id, req.body, { new: true, runValidators: true }, (err, categoryDB) => {
        if (err) {
            return res.status(400).json({
                ok: false,
                err
            });
        }
        res.json({
            ok: true,
            category: categoryDB
        });

    })
});

Request payload:

{"description":"Saladitos","errors":{},"_id":"5e5940dd7c567e1891c32cda","__v":0}

And the response:

"Validation failed: _id: Cannot read property 'ownerDocument' of null, description: Cannot read property 'ownerDocument' of null"
3 Answers

This is the contract of findByIdAndUpdate:

A.findByIdAndUpdate(id, update, options, callback)

Your update object is req.body which contains _id. Am guessing that it will try to update _id as well, which should not happend.

Try to specify which columns you want to update

 Model.findByIdAndUpdate(id, { description: req.body.description, ... }, options, callback)

Hope this helps.

I can see you might not change the ObjectId:_id into other names. But for people who had done that and see a similar problem, Check this. https://liuzhenglai.com/post/5dbd385f8dea5b6b578765d9

So you probably need to change your code into this

const id = request.params.id
Model.findByIdAndUpdate(
        id, 
        {id:id ,description: req.body.description, ... }, 
        {runValidators: true, context: 'query'},
        callback
)

You don't have to say {id: id} just pass context is equal to query like this

           {runValidators: true, context: 'query'}
Related