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>
<% } %>