javascriptnode.jsmongodbmongojs

MongoJS Not Deleting By ID


 async deleteRecipeById(recipeId){
    try{
        const client = new MongoClient(this.uriString);
        
        await client.connect();
        const db = client.db(this.databaseString);
        const recipeCollection = db.collection(this.collectionString);

        //console.log(await recipeCollection.find({recipeName:recipeName}).toArray());
        var recipeIdAsObject = new ObjectId(recipeId);
        var result = recipeCollection.deleteMany({"_id":recipeIdAsObject});
        client.close();
        return result;
    }
    catch(e){
        console.error(e);
    }
}

I'm testing my mongo driver how ever I cannot for the life of my figure out why this isn't working. I run the same test with my deleteRecipeByName() and the test passes. So this to me shows that my testing fixture is fine. Meaning I know the recipe exists in the database with the correct ID.

Before I run the test I'm even calling a getRecipeByName function that I've already tested to make sure that the recipe exists with the ID I'm looking for and this is the result.

[
{
  _id: 0,
  recipeName: 'mock0',
  recipeIngredients: [ 'i0', 'i1', 'i2' ]
}
]

And there is my Test function

describe('Testing delete Recipe',()=>{
it('1. Delete known recipe',(done)=>{
    var uri = "mongodb://localhost:27017";
    var dbname = "testRecipes";
    var collectionName = "testCollectionMessy";
    let driver = new MongoDriver(uri,dbname,collectionName);
    driver.dropCollection().then(()=>{//Clean collection for testing... NEVER CALL ON PRODUCTION COLLECTION
        driver.addMockData().then((p)=>{
            driver.getRecipeById(mockData[0]._id).then((p)=>{
                console.log(p);
            })
            driver.deleteRecipeById(0).then((p)=>{
                console.log(p);
                console.log(mockData[0]._id);
                assert.deepEqual(p.deletedCount,1);
                done();
            }).catch((e)=>{
                console.log(e);
                done(e);
            })
        });
    }); 
})
})

and here is mockData that I import from a JSON

[
 {"_id":0,"recipeName":"mock0","recipeIngredients":["i0","i1","i2"]},
 {"_id":1,"recipeName":"mock1","recipeIngredients":["i0","i1","i2"]},
 {"_id":2,"recipeName":"mock2","recipeIngredients":["ingredient"]}
]

Solution

  • The issue is how the receipeId is managed.

    new ObjectId(id) throws if the id is not a valid mongo object id, so you can add a snippet to manage both format like following:

     async deleteRecipeById(recipeId){
        try{
            const client = new MongoClient(this.uriString);
            
            await client.connect();
            const db = client.db(this.databaseString);
            const recipeCollection = db.collection(this.collectionString);
    
            var recipeIdAsObject;
            if(/^(?=[a-f\d]{24}$)(\d+[a-f]|[a-f]+\d)/i.test(recipeId)){
               recipeIdAsObject = new ObjectId(recipeId);
            } else {
               recipeIdAsObject = recipeId
            }
    
            var result = recipeCollection.deleteMany({"_id":recipeId});
            client.close();
            return result;
        }
        catch(e){
            console.error(e);
            // it is dangerous to ignore errors
        }
    }
    

    I would suggest choosing only one format otherwise it could be difficult to do query across applications.