Error: grid.mongo.GridStore is not a consstructor ,Using mongoose, Grid-fs-stream and grid multer storage

Viewed 2943

I am getting the following error mentioned. The basic configs are as follow: I have uploaded the files on the server I want to download them but getting these errors I called a POST request to /api/files/delete/${fileId} Which should call the route and give back the file to the browser instead getting the error with the Grid related module.

MONGODB_CONNECTION_STRING = mongodb://localhost:27017/Cstore

Db structure={Cstore:{uploads.files,uploads.chunks,users}}

On requesting POST         axios.post(`/api/files/delete/${fileId}`)

Getting error: 

     this._store = new grid.mongo.GridStore(grid.db, this.id || new grid.mongo.ObjectID(), this.name, this.mode, options);
[0]                 ^
[0] 
[0] TypeError: grid.mongo.GridStore is not a constructor
[0]     at new GridReadStream (/home/lenovo/Desktop/react/cstore/node_modules/gridfs-stream/lib/readstream.js:68:17)

This is server.js

      app.get('/image/:filename', (req, res) => {
    gfs.files.findOne({ 
      _id: mongoose.Types.ObjectId(req.params.filename)
      // filename: req.params.filename.toString()
    }, (err, file) => {
      // Check if file
      if (!file || file.length === 0) {
        console.log("not found")
        return res.status(404).json({
          
          err: 'No file exists'
        });
      }

      // Check if image
      if (file.contentType === 'image/jpeg' || file.contentType === 'image/png') {
        // Read output to browser
        console.log(file)
        let id=file._id;

        const readStream = gfs.createReadStream(
          {
            _id: mongoose.Types.ObjectId(req.params.filename)
          }
          // {
          // _id: id
          // }
        )
        readStream.on('error', err => {
            // report stream error
            console.log(err);
        });
        // the response will be the file itself.
        readStream.pipe(res);

      //   let readstream = gfs.createReadStream(mongoose.Types.ObjectId(file._id))
      //   readstream.pipe(res)
      // } else {
        res.status(404).json({
          err: 'Not an image'
        });
      }
    });
  });



  

    mongoose.Promise = global.Promise;
      mongoose.connect(
        mongoURI,
        {
          useNewUrlParser: true,
          useUnifiedTopology: true,
        },
        (err) => {
          if (err) throw err;
          console.log('MongoDB connection established');
        }
      )
      const connection = mongoose.connection;
    
      ///  HANDLING FILE
      let gfs;
      connection.once('open', () => {
        // Init stream
        gfs = Grid(connection.db, mongoose.mongo);
        gfs.collection('uploads');
      });
    
      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 = file.originalname;
              const fileInfo = {
                filename: filename,
                bucketName: 'uploads'
              };
              resolve(fileInfo);
            });
          });
        }
      })
    
      const upload = multer({ storage });

Initial:
  const express = require('express');
  const mongoose = require('mongoose');
  const cookieParser = require('cookie-parser');
  const path = require('path');

  const multer = require('multer');
  const {GridFsStorage} = require('multer-gridfs-storage');
  const Grid = require('gridfs-stream');
  const methodOverride = require('method-override')
  const crypto = require('crypto')

  const app = express();

  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));
  app.use(methodOverride('_method'));
  app.use(cookieParser());

  const dotenv=require('dotenv');
  dotenv.config({path:__dirname+'/.env'});

  const mongoURI = process.env.MONGODB_CONNECTION_STRING
4 Answers

GridStore is deprecated. You can use the GridFSBucket instance to call read and write operations on the files in your bucket. documentation

 let gfs, gridfsBucket;
  conn.once('open', () => {
   gridfsBucket = new mongoose.mongo.GridFSBucket(conn.db, {
   bucketName: 'your_bucket_name'
 });

   gfs = Grid(conn.db, mongoose.mongo);
   gfs.collection('your_bucket_name');
})

and

if(file.contentType === 'image/jpeg' || file.contentType 
 ==='image/png') 
 {
    const readStream = gridfsBucket.openDownloadStream(file._id);
    readStream.pipe(res);
 }

I also faced similar issues. The resolution for me was with mongoose version. The issue arises in the version 6.0.5 but is working in the version 5.13.7

GridStore is deprecated in mongoose version 6+.

One solution is to deprecate mongoose version to use 5+

other solution is to use GridFsBucked

import grid from 'gridfs-stream';
import mongoose from 'mongoose';

let gfs, gridfsBucket; // declare one more variable with name gridfsBucket
const conn = mongoose.connection;
conn.once('open', () => {
    // Add this line in the code
    gridfsBucket = new mongoose.mongo.GridFSBucket(conn.db, {
        bucketName: 'bucket_name'
    });
    gfs = grid(conn.db, mongoose.mongo);
    gfs.collection('bucket_name');
});

export const getImage = async (request, response) => {
    try {   
        const file = await gfs.files.findOne({ filename: request.params.filename });
        // Till version 5+ we were using this 
        // const readStream = gfs.createReadStream(file.filename);
        // readStream.pipe(response);
        // For version 6+, Replace these two lines with the lines below
        const readStream = gridfsBucket.openDownloadStream(file._id);
        readStream.pipe(response);
    } catch (error) {
        
    }
}
Related