I am new to NodeJS(Express). I am trying to build an API that will list the "Rooms" of a Hotel, and "Photos" for each room.
What I am trying to do is: - get a list of all rooms by a hotel - loop through this list of rooms and add photos - return JSON with rooms and photos
My problem is that I can not seem to attach the "photos" result to the "rooms result.
async.waterfall([
// Function 1
function(callback) {
// Find all Hotel Rooms
Room.find({ 'hotel': req.params.hotel_id})
.exec(function(err, rooms) {
callback(null, rooms); // Send rooms to function 2
});
},
// Function 2
function(rooms, callback) {
// Loop through each room to get photos for each room
rooms.forEach(function(room) {
// Get photos for room
RoomPhoto.find({ 'room': room._id})
.exec(function(err, photos) {
// I want to add these "photos" to the main "rooms" object, but attached to each individual "room"
room.photos = JSON.stringify(photos);
});
})
console.log(rooms)
callback(null, rooms);
}
], function(err, results) {
if(err) console.log('err');
res.json(results);
});
Any help would be greatly appreciated, as I have been hours trying to figure it out.
Thanks
Ray
I have updated my script to this, but the "photos" are still not going into the final "rooms" object. I have included the code and also the console output.
Code:
exports.index = function(req, res, next) {
Room.find({ 'hotel': req.params.hotel_id})
.exec(function(err, rooms) {
async.each(rooms, function(room, room_cb) {
console.log('Room Name: ' + room.name);
RoomPhoto.find({ 'room': room._id})
.exec(function(err, photos) {
console.log('Photos: ' + photos);
room.photos = photos;
// photos should now be in the main "rooms" object right??
// I can console.log the photos here to prove they exists
room_cb();
});
}, function(err) {
if(err) {
console.log('Error: ' + err)
}
else {
// But the photos are not in the final "rooms" object
console.log('FINAL ROOMS OBJECT, why are the photos not here??');
console.log(rooms);
res.json(rooms);
}
})
});
};
Here is the console output for the above script:
Room Name: Test Room 1
Room Name: Test Room 2
Photos:
{ _id: 5acd3094e0026f38ca4b44bc, src: 'https://picsum.photos/200/300/?image=252', room: 5acd3094e0026f38ca4b44bb, __v: 0 }Photos:
{ _id: 5acd30c8cec87777eefcd32d, src: 'https://picsum.photos/200/300/?image=252', room: 5acd30c8cec87777eefcd32c, __v: 0 }FINAL ROOMS OBJECT
[ { _id: 5acd3094e0026f38ca4b44bb, name: 'Test Room 1', hotel: 5accd4e1734d1d55c3195c84, __v: 0 }, { _id: 5acd30c8cec87777eefcd32c, name: 'Test Room 2', hotel: 5accd4e1734d1d55c3195c84, __v: 0 } ]
Since the function RoomPhoto is also asynchronous, then you need to wait until all the photos are loaded before calling the callback function. Like that:
// Function 2
function(rooms, callback) {
// https://caolan.github.io/async/docs.html#each
// Loop through each room to get photos for each room
async.each(rooms, function(room, room_cb) {
// Get photos for room
RoomPhoto.find({ 'room': room._id})
.exec(function(err, photos) {
room.photos = JSON.stringify(photos)
room_cb()
});
}, function (err) {
console.log(rooms)
callback(null, rooms)
})
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With