I am new to Node.js and right now I am trying to display all my images of a logged in user from my database to my ejs file. I have set up all the code but i have a problem where I don’t know how to properly display all images. I have also tried async functions
but i don’t seem to do them the right way. I have tried multiple thinks like for...of
and forEach
.
I noticed that if i do a try catch
i get the error Cannot set headers after they are sent to the client
which is probably because i can’t use res.render
multiple times. Alongside this error I also get this error: UnhandledPromiseRejectionWarning: TypeError: req.next is not a function
even if I don’t use try catch
. At this point I don’t know what is the proper way to display all images so I came here for help. The problem is that i don’t realy properly understand the async functions
and if they should be used in this case.
The for loop
works fune and the problem accurs when I try res.render
, because if i console.log(img)
I get all the images of that user. The problem is also that I can display 1 image but i cant display multiple
Have gone through multiple documentations and cases and didn’t find a solution so I came here
app.get('/galery/galery', (req, res) => { const selectImg = conn.query("SELECT pic_name, user_id FROM galery WHERE user_id =?", [req.session.userId], function (err, result){ if (result && result.length) { for(let i = 0; i < result.length; i++){ var imgName = await result[i].pic_name var img = 'upload/' + imgName res.render('./galery/galery', {img: img, imgName: imgName}) console.log(img) } return res.end() } else { res.render('./galery/galery') } }) })
and this is my ejs file
<div class="galery"> <% if (typeof img !== 'undefined') {%> <img src= "<%= img %>" alt="img" width="600" height="400"> <div class="style"><%= imgName %> <form action="deleteImg.php" method="post"> <input type="hidden" name="deleteImg" value=""> <button class="btn btn-danger" name="delete" type="submit" >delete</button> </input> </form> </div> <% }%> </div>
Advertisement
Answer
As far as I can tell your problem is that you render (as u said) multiple times inside the loop. That is not how it suppose to happen. You have to render only once.
You are getting image data correctly, then modify it in a way you want and collect at one place, once done render it with the new data.
app.get('/galery/galery', (req, res) => { const query = 'SELECT pic_name, user_id FROM galery WHERE user_id =?'; conn.query(query, [req.session.userId], function (err, result) { if (result && result.length) { const images = []; for (const item of result) { const imgName = item.pic_name; const img = 'upload/' + imgName; // { img, imgName } is shorthand for { img: img, imgName: imgName } images.push({ img, imgName }); } res.render('./galery/galery', { images }); } else { res.render('./galery/galery', { images: []}); } }); });
Now in ejs
side, you have a list of images already and you need to iterate over it to display correctly.
<% for(const image of images) { %> <div class="galery"> <img src="<%= image.img %>" alt="img" width="600" height="400"> <div class="style"><%= image.imgName %> <form action="deleteImg.php" method="post"> <input type="hidden" name="deleteImg" value=""> <button class="btn btn-danger" name="delete" type="submit" >delete</button> </form> </div> </div> <% } %>