mongoose — check if ObjectId exists in an array

Problem

Following is an example model:

UserModel == {
    name: String,
    friends: [ObjectId],
}

friends corresponds to a list of id of objects of some other model for example AboutModel.

AboutModel == {
    name: String,
}

User.findOne({name: 'Alpha'}, function(error, user){
    About.find({}, function(error, abouts){ // consider abouts are all unique in this case
        var doStuff = function(index){
            if (!(about.id in user.friends)){
                user.friends.push(about.id);
                about.save();
            }
            if (index + 1 < abouts.length){
                doStuff(index + 1)
            }
        }
        doStuff(0) // recursively...
    })
})

In this case, the condition 'about.id in user.friends` seems to be always false. How? Is this to do with the type of ObjectId or the way it is saved?

Note: ObjectId is short for Schema.ObjectId; I don't know if that's an issue in itself.

Problem courtesy of: p0lAris

Solution

If about.id is a string representation of an ObjectID and user.friends is an array of ObjectIDs, you can check if about.id is in the array using Array#some:

var isInArray = user.friends.some(function (friend) {
    return friend.equals(about.id);
});

The some call will iterate over the user.friends array, calling equals on each one to see if it matches about.id and stop as soon as it finds a match. If it finds a match it returns true, otherwise false.

You can't use something simpler like indexOf because you want to compare the ObjectIDs by value, not by reference.

Solution courtesy of: JohnnyHK

Discussion

I use lo-dash and do something like that :

var id_to_found = '...';
var index = _.find(array, function(ch) {
     return ch == id_to_found ;
});
if ( index!=undefined ) {
     // CHILD_ALREADY_EXISTS
} else {
     // OK NOT PRESENTS
}
Discussion courtesy of: GPERREYMOND

I believe this is a javascript question rather than a Node.js/Mongoose question - so it really doesn't belong in the way it is currently now.

Also, the issue with about.id in user.friends is that the object pointed to by about.id and objects in user.friends are different; and I believe in checks for the equality of the object.

Anyway, the answer is available on stack overflow to check where an element exists in an array —

user.friends.indexOf(about.id) > -1
Discussion courtesy of: p0lAris

This recipe can be found in it's original form on Stack Over Flow.