简体   繁体   中英

Deleting an element from an Object in MongoDB with Mongoose

I am trying to remove a card from the user's current project. Each card follows the CardSchema .

I'm building a kanban board - this might be useful to know.

However, I've been unable to delete a card.

The structure of my database for this is as follows:

"cards": [
    {
        "pending": {
            "cardIDHere": {
                // stuff here
            }
        },
        "inprogress": {},
        "completed": {}
    }
]

// or

project
    | - cards [Array]
        | - 0 [Object]
            | - pending [Object]
                | - cardIDHere [Object]
            | - inprogress [Object]
            | - completed [Object]
   

In other words, to get to a card you need: cards.0.<panel-name>.<card-id> .

panel-name is the parent of the card: pending , etc.

My code:

exports.updateCardPlace = async(req, res, next) => {
    const parent = await Card.findOne({"id":req.body.id});
    const path = `cards.0.${parent.panel}`;

    try{
        await Card.findOneAndDelete({"id": req.body.id});
        res.status(204).json({
            status: "Success"
        })
    } catch(err){
        res.status(300).json({
            status: "Error",
            message: err.message
        })
    }
}

Please note, req.body.id is the correct value, and parent.panel is valid.

However, I test this once - POST request comes back with code 204 . Ok, great. However, my error alert is shown.

So, I reload - maybe it's been deleted, as it should have been.

Nope, still there. Let's try deleting the card again.

Ah - an error this time:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'panel' of null
    at exports.updateCardPlace

I have absolutely no idea what this is about - could anyone help me?

Card Schema :

const cardSchema = new mongoose.Schema({
    summary: String,
    description: String,
    tags: Array,
    urgency: String,
    id: String,
    panel: String
});

Project Schema :

const projectSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Project name is required']
    },
    type: String,
    photo: String,
    members: [String],
    code: String,
    cards: [{
        "pending": { 
            type: mongoose.Schema.Types.Object,
            ref: 'Card'
        },
        "inprogress": { 
            type: mongoose.Schema.Types.Object,
            ref: 'Card'
        },
        "issues": { 
            type: mongoose.Schema.Types.Object,
            ref: 'Card'
        },
        "completed": { 
            type: mongoose.Schema.Types.Object,
            ref: 'Card'
        }
    }],
    tags: Object
});

Let's try something like this:

const parent = await Card.findOne({"id":req.body.id});

try {
    await Card.findOneAndDelete({"id": req.body.id});
    await Project.updateOne(
        { `cards.${parent.panel}.${req.body.id}`: { $exists: true } },
        { $unset: { `cards.$.${parent.panel}.${req.body.id}`: "" }});
    res.status(204).json({
        status: "Success"
    })
} catch(err){
    res.status(300).json({
        status: "Error",
        message: err.message
    })
}

After looking at this question , it looks like you need to remove the reference on the Project model as well.

For my filter, I use { `cards.${parent.panel}.${req.body.id}`: { $exists: true } }} . I didn't specify the index 0 because I'm assuming there may be more than one element in the cards array. In the update document, I use the positional operator $ to unset the <panel-name>.<card-id> field of the matching element in the cards array.

perhaps what you want is...

const parent = await Card.findOne({"_id":req.body.id});

mind the underscore in id ( '_id' )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM