Nadia Ghufran
Nadia Ghufran

Reputation: 29

Is it possible to put a render function inside a for loop in express?

So i am rendering a webpage after i go through a for loop but the problem is that when i put the render inside the for loop, the same page gets renders multiple times which ends up giving me the error:

Cannot set headers after they are sent to the client

^^ This crashes my app.

If i put my render outside the for loop, the data that i am pulling cannot be pulled.

router.get('/dashboard', (req, res) =>
{
const roomArr = [];

model.findById(req.session.userLogin._id)
.then((user) =>
{

    user.bookedRooms.forEach((eachRoom) =>
    {
        console.log(eachRoom);

        roomModel.findById(eachRoom)
        .then((roomInfo) =>
        {
            console.log(roomInfo);
            console.log(`Rooms Array: ${roomArr}`);
            roomArr.push(roomInfo); 
        })
        .catch((err) =>
        {
            console.log(`Could not book rooms: ${err}`);
        })
    })

    res.render('registration/dashboard', {
        rooms: roomArr,
        ttl: title,
        sty: style
    })

})

})

^^ As shown by my code above, my goal is to pull the id of bookedRooms(array) inside my session and then check if that id matches the roomsID in the room collection. If those 2 id's match, that means the user has booked a room.

The problem i am having is that my rooms are not being pulled and i think that might be because my render is not after my .then.

I guess my main question is does my render have to be right after my .then??

Upvotes: 1

Views: 600

Answers (1)

Jaromanda X
Jaromanda X

Reputation: 1

Assuming user.bookedRooms is a regular Javascript array

do as follows

router.get('/dashboard', (req, res) => 
    model.findById(req.session.userLogin._id)
    .then(user => Promise.all(user.bookedRooms.map(eachRoom => roomModel.findById(eachRoom))))
    .then(rooms => res.render('registration/dashboard', {
        rooms,
        ttl: title,
        sty: style
    }))
    .catch(err => console.log(`Could not book rooms: ${err}`))
)

Explanation:

  1. model.findById(req.session.userLogin._id) - does what it did before
  2. use Promise.all on the array of Promises returned by ...
  3. user.bookedRooms.map which, for each eachRoom returns the promise returned by
  4. roomModel.findById(eachRoom) ... so far so good?
  5. once ALL promises resolve, the result is in rooms in the .then(rooms
  6. res.render('registration/dashboard', ... etc, does what you do in your code

I use rooms as the name of the result, to shortcut the

res.render('registration/dashboard', {
    rooms: roomsArr,
    ttl: title,
    sty: style
})

to

res.render('registration/dashboard', {
    rooms,
    ttl: title,
    sty: style
})

Upvotes: 2

Related Questions