Reputation: 35
I'm using MongoDB with Express and I have a fetch to get a list of users and sort them by the amount of wins they achieved. The problem is that 80% of the time the same code returns a sorted list with no problem, but 20% of the time the response is an empty array [].
I have promises everywhere and I have crosschecked that the problem is in mongoDB's find method, not in the sort method. I know about concurrency and stuff, I just don't understand why this does not work.
app.get("/api/account/getSortedRank", (req, res) => {
const { query } = req;
const { userId } = query;
var getFriends = [];
User.findOne(
{
_id: userId
},
(err, user) => {
if (err) {
console.log("Server error");
}
user.friends.forEach(userFound => {
getFriends.push(userFound.user);
});
// getFriends is always correct!
}
).then(() => {
User.find({
_id: { $in: getFriends }
})
.sort({ wins: -1 })
.then(sortedUsers => {
// 50% of the time sortedUsers is an empty array!
let usersList = [];
sortedUsers.forEach(user => {
usersList.push({
firstName: user.firstName,
lastName: user.lastName,
userID: user._id,
wins: user.wins
});
});
return res.send({
success: true,
usersList
});
});
});
});
Upvotes: 1
Views: 118
Reputation: 311925
You're mixing callbacks and promises here, which is likely ending up executing the findOne
query twice, with different completion times. So getFriends
is sometimes populated in time, but other times it isn't.
Instead, move the find
query inside the findOne
callback:
User.findOne(
{
_id: userId
},
(err, user) => {
if (err) {
console.log("Server error");
}
var getFriends = [];
user.friends.forEach(userFound => {
getFriends.push(userFound.user);
});
// getFriends is always correct!
User.find({
_id: { $in: getFriends }
})
.sort({ wins: -1 })
.then(sortedUsers => {
let usersList = [];
sortedUsers.forEach(user => {
usersList.push({
firstName: user.firstName,
lastName: user.lastName,
userID: user._id,
wins: user.wins
});
});
return res.send({
success: true,
usersList
});
});
}
);
Upvotes: 1