Reputation: 4578
I have a Student.find query which is run inside Room.find query as below:
Room.find({ schoolID: mongoose.mongo.ObjectId(user.schoolID) }).sort({'level':'ascending','name':'ascending'}).then(function (roomList) {
if (!roomList){
console.log("no class room found")
}else{
console.log("class room found: " + roomList.length)
var studentList = []
for (var i = 0; i < roomList.length; i++){
console.log(i)
console.log("class room id: " + roomList[i]._id)
console.log("class room name: " + roomList[i].name)
Students.find({ schoolID: mongoose.mongo.ObjectId(user.schoolID), classRoomID: mongoose.mongo.ObjectId(roomList[i]._id) }).sort({'firstName':'ascending'}).then(function (data) {
if (!data){
console.log("no data found")
return res.status(200).send({success: true, msg: 'No data found.'});
}else{
console.log("214 ada data: " + data.length)
studentList[i] = data
console.log("studentList " + i)
console.log(studentList[i])
}
});
}
res.json({success: true, token: 'JWT ' + token, id: user._id, user: user, classRoom: roomList, students: studentList});
}
});
In the db, there are 6 class room and a different number of students for each class. In the console.log, I was expecting to see something like:
class room id: 01
class room name: my first class
studentList 0:
list of students from first class
class room id: 02
class room name: my second class
studentList 1:
list of students from 2nd class
class room id: 03
class room name: my third class
studentList 2:
list of students from 3rd class
because I assume the Students.find will be executed right after I output the console.log("class room name: + roomList[i].name)
But it turns out all the console.log("class room id") and console.log("class room name") are printed out first, then only it seems Students.find
are executed, because my output is something like this:
class room id: 01
class room name: my first class
class room id: 02
class room name: my second class
class room id: 03
class room name: my third class
class room id: 04
class room name: my fourth class
class room id: 05
class room name: my fifth class
class room id: 06
class room name: my six class
list of students
list of students
list of students
list of students
list of students
list of students
If this is the case, how do I do a proper nested query?
Upvotes: 0
Views: 189
Reputation: 18525
Mongoose queries are not promises. They have a .then() function for co and async/await as a convenience. If you need a fully-fledged promise, use the .exec() function.
Try:
Room.find({
schoolID: mongoose.mongo.ObjectId(user.schoolID)
}).sort({
'level': 'ascending',
'name': 'ascending'
}).exec().then(function(roomList) {
if (!roomList) {
console.log("no class room found")
} else {
console.log("class room found: " + roomList.length)
var studentList = []
for (var i = 0; i < roomList.length; i++) {
console.log(i)
console.log("class room id: " + roomList[i]._id)
console.log("class room name: " + roomList[i].name)
Students.find({
schoolID: mongoose.mongo.ObjectId(user.schoolID),
classRoomID: mongoose.mongo.ObjectId(roomList[i]._id)
}).sort({
'firstName': 'ascending'
}).exec().then(function(data) {
if (!data) {
console.log("no data found")
return res.status(200).send({
success: true,
msg: 'No data found.'
});
} else {
console.log("214 ada data: " + data.length)
studentList[i] = data
console.log("studentList " + i)
console.log(studentList[i])
}
});
}
res.json({
success: true,
token: 'JWT ' + token,
id: user._id,
user: user,
classRoom: roomList,
students: studentList
});
}
});
The other issue you have is that you are trying to do for loop with async. It does not work that way ... (for loop would not wait and will keep going) either use Promise.All
or a something among these lines
Upvotes: 1
Reputation: 1133
Room.find({ schoolID: mongoose.mongo.ObjectId(user.schoolID) }).sort({'level':'ascending','name':'ascending'}).then(function (roomList) {
if (!roomList){
console.log("no class room found")
}else{
console.log("class room found: " + roomList.length)
var promsies = [];
if (roomList.length) return res.status(200).send({success: true, msg: 'No data found.'});
for (var i = 0; i < roomList.length; i++){
console.log(i)
console.log("class room id: " + roomList[i]._id)
console.log("class room name: " + roomList[i].name)
promsies.push(Students.find({ schoolID: mongoose.mongo.ObjectId(user.schoolID), classRoomID: mongoose.mongo.ObjectId(roomList[i]._id) }).sort({'firstName':'ascending'}));
}
Promise.all(promsies).then(function (studentList) {
res.json({success: true, token: 'JWT ' + token, id: user._id, user: user, classRoom: roomList, students: studentList});
});
}
});
Upvotes: 1