oalva-rez
oalva-rez

Reputation: 86

How can I send several images through the response object to my front end using MongoDB, GridFs Node.Js?

I have images linked to a user in a MongoDB collection that I can successfully store and retrieve using multer and GridFS. I am having trouble with finding a way to stream the multiple images through the response header. I have successfully sent one image but cannot send several images at once to my front end.

Here is my route and my initial attempt:

router.get("/my-projects", async (req, res) => {
  res.set("Content-Type", "image/png");
  const db = mongoose.connections[0].db;

  gfs = new mongoose.mongo.GridFSBucket(db, { bucketName: "uploads" });
  await gfs
    .find({
      metadata: {
        _id: req.user._id,  // Finding collection based off user id
      },
    })
    .toArray((err, files) => { // "files" is in an array type of user images
      if (!files || files.length === 0) {
        return res.status(404).json({
          error: "No files exist",
        });
      }
      for (const file of files) {
        const imageStream = gfs.openDownloadStreamByName(file.filename)
        imageStream.pipe(res);
      }
    });
});

Here is where the problem lies. I am essentially piping the first stream that finishes. How can I pipe all images/streams in an array type?

for (const file of files) {
        const imageStream = gfs.openDownloadStreamByName(file.filename)
        imageStream.pipe(res);
      }

The Front End:

async function getProjects() {
      const response = await fetch(
        "http://localhost:3001/api/dashboard/my-projects",
        {
          method: "GET",
          headers: {
            Authorization: `Bearer ${localStorage.getItem("token")}`,
          },
        }
      );
      const blob = await response.blob();
      const imageURL = URL.createObjectURL(blob);
      console.log(imageURL); // returns "blob:http://localhost:5173/6b40e4da-a70e-42da-b8c8"
    }

The blob that returns and renders to an img tag is one of the three images stored. It seems to render the first image available so it seems random. I realize that I am not going to get all three images through one download stream but I don't know how to separate the download streams to an array type so I can loop through in the front end.

Bonus Question: Is there an easier way to store and retrieve multiple images using another technology other than MongoDB? Should I split the data between two different Dbs such as firebase for images and mongodb for user info? Am I going crazy?

Upvotes: 0

Views: 81

Answers (0)

Related Questions