Emil Kais
Emil Kais

Reputation: 11

mongodb field of array type won't update length when using .push()

Here is the code that is trying to add a user to a schema:

var roomSchema = new Schema({
    name: { type: String, required: true},
    connections: { type: [ { userId: String } ] },
    content: { type: String, default: ""},
    isFull: { type: Boolean, default: false}
});

roomSchema.methods.addUser = function(username, callback) {
this.updateAsync( { $push: { connections: { userId: username }  } } )
.then(function(status) {
    return this.saveAsync();
})
.catch(function(afterPushErr) {
    console.log('After push error');
    throw afterPushErr;
})
.catch(function(saveErr) {
    console.log('save Error');
    throw saveErr;
});

Promise.all(this.connections)
.then(function() {
    if(this.connections.length >= 5) {
        this.updateAsync( { isFull: true })
        .then(function(status) {
            return;
        })
        .catch(function(updateErr) {
            console.log('update Error!');
            throw updateErr;
        });
    }
});

}

and then the code that calls it (which correctly imports the above function): (Note: this is just a quick test function to make sure that there will only be a maximum of 5 users per room)

var populateRooms = function() {
    var names = [
        'asas',
        'asas2',
        'asas3',
        'asas4',
        'asas5',
        'asas6'];

    var emails = [
        '[email protected]',
        '[email protected]',
        '[email protected]',
        '[email protected]',
        '[email protected]',
        '[email protected]'];

    for(var i=0; i<6; ++i) {
    Room.findOneAsync( { isFull: false })
        .then(function(freeRoom) {
            var newUser = new User({
                username : names[i],
                email : emails[i],
                password : 'Asasas1',
                isPlaced: true,
                roomName: freeRoom.name
            });
            freeRoom.addUser(newUser.username);
            return newUser;
        })
        .then(function(newUser) {
            newUser.saveAsync();
        })
        .catch(function(err) {
            throw err;
        });
    }
    return true;
}

typically what I will see in the console is just the last user that was pushed rather than the entire list and because of that I am unable to see whether or not the list is of length >= 5.

On the mongo console I see this for the room schema:

{ "_id" : ObjectId("5882c3eefab3081700444972"), "name" : "1484964846968_0", "isFull" : false, "content" : "", "connections" : [ { "userId" : "asas5", "_id" : ObjectId("5882c3effab308170044497f") }, { "userId" : "asas6", "_id" : ObjectId("5882c3effab308170044497d") }, { "userId" : "asas4", "_id" : ObjectId("5882c3effab3081700444981") }, { "userId" : "asas6", "_id" : ObjectId("5882c3effab308170044497d") }, { "userId" : "asas5", "_id" : ObjectId("5882c3effab308170044497f") }, { "userId" : "asas4", "_id" : ObjectId("5882c3effab3081700444981") }, { "userId" : "asas3", "_id" : ObjectId("5882c3effab3081700444983") }, { "userId" : "asas", "_id" : ObjectId("5882c3effab3081700444987") }, { "userId" : "asas2", "_id" : ObjectId("5882c3effab3081700444985") }, { "userId" : "asas3", "_id" : ObjectId("5882c3effab3081700444983") }, { "userId" : "asas2", "_id" : ObjectId("5882c3effab3081700444985") }, { "userId" : "asas", "_id" : ObjectId("5882c3effab3081700444987") } ], "__v" : 12 } { "_id" : ObjectId("5882c3eefab3081700444973"), "name" : "1484964846978_1", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444974"), "name" : "1484964846980_2", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444975"), "name" : "1484964846980_3", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444976"), "name" : "1484964846981_4", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444977"), "name" : "1484964846981_5", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444978"), "name" : "1484964846982_6", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444979"), "name" : "1484964846984_7", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab308170044497a"), "name" : "1484964846984_8", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab308170044497b"), "name" : "1484964846984_9", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 }

Edit this is the new error on the promise code for addUser

(node:4648) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'connections' of undefined (node:4648) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property 'connections' of undefined After push error After push error save Error save Error Unhandled rejection TypeError: Cannot read property 'saveAsync' of undefined at C:\someApp\app\models\room-model.js:19:14 at tryCatcher (C:\someApp\node_modules\bluebird\js\release\util.js:16:23)

Upvotes: 1

Views: 126

Answers (1)

hankchiutw
hankchiutw

Reputation: 1662

In the test function, you put the asynchronous call(Room.findOne) inside the for loop. Thus you got the same freeZoom for each loop.(which is not what you want)

Check this question: Asynchronous Process inside a javascript for loop

Another suggestion, this.update inside the addUser function is also asynchronous and may not act like what you want in some situation.

Upvotes: 1

Related Questions