Skip to content
Advertisement

Node.js display all images of a user in ejs from database

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>
<% } %>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement