1

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>
Anzeko
  • 15
  • 5
  • "I have set up all the code but i have a problem where I don't know how to properly display all images": try to get just 1 image, and if that succeeds, it will be easier to get "all images". – Luuk Nov 25 '21 at 11:26
  • BTW: This question/answer tells you how to display 1 image: [Display images in HTML + Nodejs](https://stackoverflow.com/questions/21235696/display-images-in-html-nodejs) – Luuk Nov 25 '21 at 11:30
  • I have already tried that and forget to put in the discription. I can easily display 1 image but i can't display multiple images – Anzeko Nov 25 '21 at 11:39
  • You also wrote "....which is probably because i can't use res.render multiple times.". So you can try to find another way to display an image (see the link I commented earlier) – Luuk Nov 25 '21 at 11:41
  • yes I want t pass a variable to ejs with res.render where I save the image name so I can display it. That link doesn't help me. I can display images freely. But i can't display every image from the database because I have already sent a `header` with res.render. I want to find a different solution besides res.render or If i need to create a async function with res.render. – Anzeko Nov 25 '21 at 11:51
  • This might help: [Error: Can't set headers after they are sent after res.render() call](https://stackoverflow.com/questions/52923099/error-cant-set-headers-after-they-are-sent-after-res-render-call/52923229) – Luuk Nov 25 '21 at 11:56
  • @Luuk sadly that doesn't help have already tried and get the same errors – Anzeko Nov 25 '21 at 12:01

1 Answers1

1

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>
<% } %>
n1md7
  • 2,854
  • 1
  • 12
  • 27
  • 1
    Wow this works. Thank you a lot. This is a really great and simple solution with `arrays`. And now as I go through your code i just feel a little bit dumb how I didn't come up to use `arrays`. Thank you very much for help – Anzeko Nov 30 '21 at 10:06
  • No worries, everyone starts from somewhere at some point. That's what we do here, helping each other. – n1md7 Nov 30 '21 at 10:11