In "pages/api", trying to print out GridFS images from MongoDB database on the client. Works in (another) MERN-Stack project but seems that I have a problem in Next.js.
pages/api/uploads/files/index.js Works(I'm getting the returned files in the client-side):
import Grid from 'gridfs-stream'
Grid.mongo = mongoose.mongo;
export default async function handler(req, res) {
const { method } = req
const conn = await mongoose.createConnection(db, {
useNewUrlParser: true,
useUnifiedTopology: true
});
switch (method) {
case 'GET':
try {
const files = await conn.db.collection("uploads.files").find().toArray()
if(!files || files.length === 0) {
return res.status(404).json({ err: 'No file exist' });
} else {
files.map(file => {
if (
file.contentType === 'image/jpeg' ||
file.contentType === 'image/jpg' ||
file.contentType === 'image/png'
) {
file.isImage = true;
} else {
file.isImage = false;
}
});
return res.send(files);
}
} catch (error) {
res.status(400).json({ itemnotfound: "No file found" })
}
break
default:
res.status(400).json({ itemnotfound: "No file" })
break
}
}
pages/api/uploads/image/[filename].js The issue(it logs "1 API / 3 API")
import Grid from 'gridfs-stream'
Grid.mongo = mongoose.mongo;
export default async function handler(req, res) {
const {
query: { filename },
method,
} = req
const conn = await mongoose.createConnection(db, {
useNewUrlParser: true,
useUnifiedTopology: true
});
conn.once('open', () => {
gfs = Grid(conn.db);
gfs.collection('uploads');
});
switch (method) {
case 'GET':
try {
const file = await conn.db.collection("uploads.files").findOne({ filename: filename })
if(!file || file.length === 0){
return res.status(404).json({ err: "Could not find file" });
} else if(
file.contentType === 'image/jpeg' ||
file.contentType === 'image/jpg' ||
file.contentType === 'image/png'
) {
console.log("1 API ", file) // gets printed out
const readstream = gfs.createReadStream(file.filename);
readstream.pipe(res);
} else {
console.log("2 API")
res.status(404).json({ err: 'Not an image' });
}
} catch (error) {
console.log("3 API") // after "1 API", this gets called
res.status(400).json({ itemnotfound: "No image found" })
}
break
default:
res.status(400).json({ itemnotfound: "No image" })
break
}
}
In the client side I have an img tag that waits for the image:
pages/index.js
<img key={f.uploadDate} src={`/api/uploads/image/${f.filename}`} alt={f.filename} width="50" height="50"></img>
It's probably a problem with readstream.pipe(res), since console.log prints out "1 API"(and the file) and then "3 API", but I cannot find out what.
Thanks in advance!
Found the Issue. The following line doesn't work:
conn.once('open', () => {...})
Apparently, 'open()' is deprecated and you can find more information here: https://github.com/Automattic/mongoose/issues/5399
So I just delete it but kept the lines that were inside in the outher block:
...
const conn = await mongoose.createConnection(db, {
useNewUrlParser: true,
useUnifiedTopology: true
});
gfs = Grid(conn.db);
gfs.collection('uploads');
switch (method) {
...