TypeError: grid.mongo.GridStore is not a constructor
Hi everyone. I was trying out a youtube tutorial of this link. This is my code.
const bodyParser = require("body-parser");
const path = require("path");
const crypto = require("crypto");
const mongoose = require("mongoose");
const multer = require("multer");
const { GridFsStorage } = require("multer-gridfs-storage");
const Grid = require("gridfs-stream");
const methodOverride = require("method-override");
const app = express();
// Middleware
app.use(bodyParser.json());
app.use(methodOverride("_method"));
app.set("view engine", "ejs");
// Mongo URI
const mongoURI = "mongodb://localhost:27017/MongoFileUploads";
// Create mongo connection
const connection = mongoose.createConnection(mongoURI);
// Init GFS
let gfs;
connection.once("open", () => {
// Init stream
gfs = Grid(connection.db, mongoose.mongo);
gfs.collection("uploads");
});
// Create a storage engine
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString("hex") + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: "uploads",
};
resolve(fileInfo);
});
});
},
});
const upload = multer({ storage });
// @route GET /
// @desc Loads form
app.get("/", (req, res) => {
res.render("index");
});
// @route POST /upload
// @desc Upload file to DB
app.post("/upload", upload.single("file"), (req, res) => {
// res.json({ file: req.file });
res.redirect("/");
});
// @route GET /files
// @desc Display all files in JSON
app.get("/files", (req, res) => {
gfs.files.find().toArray((err, files) => {
if (err) {
console.log(err);
}
// Check if files exists
if (!files || files.length === 0) {
return res.status(404).json({
err: "No files exists",
});
}
// Files exists
return res.json(files);
});
});
// @route GET /files/:filename
// @desc Display single file object
app.get("/file/:filename", (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
if (err) {
console.log(err);
}
// File does not exists
if (!file || file.length === 0) {
return res.status(404).json({
err: "No file exists",
});
}
// File exists
return res.json(file);
});
});
// @route GET /image/:filename
// @desc Display image
app.get("/image/:filename", (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
if (err) {
console.log(err);
}
// File does not exists
if (!file || file.length === 0) {
return res.status(404).json({
err: "No image exists",
});
}
// Check if image
if (file.contentType === "image/jpeg" || file.contentType === "image/png") {
// Read output to browser
const readstream = gfs.createReadStream(file.filename);
readstream.pipe(res);
} else {
res.status(404).json({ error: "Not an image" });
}
});
});
const port = 5000;
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
This is the configuration for this project
{
"name": "file-upload",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"ejs": "^3.1.6",
"express": "^4.17.1",
"gridfs-stream": "^1.1.1",
"method-override": "^3.0.0",
"mongoose": "^6.0.13",
"multer": "^1.4.3",
"multer-gridfs-storage": "^5.0.2"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
When I tries to get image using the GET request route /image/:filename, I am getting this error.
/home/mikhil/eth_lab/file-upload/node_modules/gridfs-stream/lib/readstream.js:68 this._store = new grid.mongo.GridStore(grid.db, this.id || new grid.mongo.ObjectID(), this.name, this.mode, options); ^
TypeError: grid.mongo.GridStore is not a constructor at new GridReadStream (/home/mikhil/eth_lab/file-upload/node_modules/gridfs-stream/lib/readstream.js:68:17) at Grid.createReadStream (/home/mikhil/eth_lab/file-upload/node_modules/gridfs-stream/lib/index.js:53:10) at /home/mikhil/eth_lab/file-upload/app.js:125:30 at /home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/utils.js:508:9 at /home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/cursor/abstract_cursor.js:477:68 at /home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/utils.js:508:9 at completeEndSession (/home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/sessions.js:147:17) at /home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/sessions.js:157:13 at maybePromise (/home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/utils.js:494:5) at ClientSession.endSession (/home/mikhil/eth_lab/file-upload/node_modules/mongodb/lib/sessions.js:133:41) [nodemon] app crashed - waiting for file changes before starting...
I tried to search for the solution in stackoverflow, and I got this link. In there, it is saying that, I would have to install an older version of mongoose (degrade from 6.0.13 to 5.13.7). But it would bring the deprication warning. Is there any other way such that, this issue can be avoided?
Yeah the problem is gridfs-stream is written 7 years ago and it's using GridStore which is deprecated according to Mongodb doc and it's should be GridFSBucket now. I think the packages really need update