Herbertusz Herbertusz - 6 months ago 39
Node.js Question

Nested MongoDB query in NodeJS

I want to select from two collections in MongoDB with NodeJS. I select from the

chat_messages
collection, there is a userId property, and I would like to extend the resulted object with the user name with the help of ES6 Promise. I tried this:


db.collection("chat_messages")
.find({"room" : roomName})
.sort({"created" : 1})
.toArray()
.then(function(messages){
console.log(messages);
return Promise.all(messages.map(function(message){
return db.collection("chat_users")
.find({"id" : message.userId})
.limit(1)
.toArray()
.then(function(users){
message.userName = users[0].name;
});
}));
})
.then(function(messages){
console.log(messages);
})
.catch(function(error){
// ...
});


The first console.log prints this:

[
{
_id: 573b6f2af9172fd81252c520,
userId: 2,
...
},
{
_id: 57388bd913371cfc13323bbb,
userId: 1,
...
}
]


But the second looks like this:

[ undefined, undefined ]


What am I mess up?

Answer

Promise.all returns data passed into a resolve function of a promise this should work

db.collection("chat_messages")
    .find({"room" : roomName})
    .sort({"created" : 1})
    .toArray()
    .then(function(messages){
        let promises = [];

        messages.forEach(message => {
            promises.push(new Promise(resolve => {
                db.collection("chat_users")
                    .find({"id" : message.userId})
                    .limit(1)
                    .toArray()
                    .then(function(users){
                        message.userName = users[0].name;
                        resolve(message);
                    });
            }));
        });
        return Promise.all(promises);
    })
    .then(function(messages){
        console.log(messages);
    })
    .catch(function(error){
        // ...
});