mongodbexpressmongoosegridfsmulter-gridfs-storage

Mongoose save() does not work when putting documents in collection and uploading files using multer-gridfs-storage


I am trying to build a music app and while working on the back end for the app (using express), I am facing this weird issue of documents not saving in mongo collections.

I made a post route to which user submits form data, which contains the song's mp3 file and the name of the song (it will have more data later on).

I am using multer to parse multipart form data. I am able to save the mp3 file to mongoDB using multer-gridfs-storage. I want to save the song info such as name, artists etc in a different collection and here is the schema for the collection:

import mongoose from 'mongoose';

const Schema = mongoose.Schema;

const SongsInfo = new Schema({
   name: {
     type: String,
     required: true,
   },
});

const Song = mongoose.model('Song', SongsInfo);
export default Song;

index.js file:

import Grid from 'gridfs-stream';
import GridFsStorage from 'multer-gridfs-storage';

const app = express();
const conn = mongoose.createConnection(mongoURI);

let gfs;

conn.once('open', () => {
  console.log('Connected to mongodb');
  gfs = Grid(conn.db, mongoose.mongo);
  gfs.collection('songFiles');
});

// storage engine
const storage = new GridFsStorage({
  url: mongoURI,
  file: (req, file) => new Promise((resolve, reject) => {
    crypto.randomBytes(16, (err, buf) => {
      if (err) {
        return reject(err);
      }
      const filename = buf.toString('hex') + 
             path.extname(file.originalname);
      let fileInfo;

    fileInfo = {
      filename,
      bucketName: 'songFiles',
    };

      resolve(fileInfo);
    });
  }),
});
let upload;

middleWare(app);

app.post('/api/uploadSong', async (req, res) => {
  upload = multer({ storage }).any();

  upload(req, res, async (err) => {
    console.log('in');
    if (err) {
      // console.log(err);
      return res.end('Error uploading file.');
    }
    const { name } = req.body;
    // push a Song into songs collection
    const songInfo = new Song({
      name,
    });
    const si = await songInfo.save();    // (*)
    console.log(songInfo);
    res.json({
      songInfo: si,
      file: req.file,
    });
  });
});

On line (*) the server just freezes until the request gets timed out. No errors shown on console. Don't know what to do :(


Solution

  • I solved the issue finally! So what i did was bring the models in index.js file and changed up some stuff here and there..

    index.js

    const app = express();
    mongoose.connect(mongoURI); //(*)
    const conn = mongoose.connection; // (*)
    
    let gfs;
    
    conn.once('open', () => {
      console.log('Connected to mongodb');
      gfs = Grid(conn.db, mongoose.mongo);
      gfs.collection('songFiles');
    });
    
    // models
    const Schema = mongoose.Schema; //(***)
    
    const SongsInfo = new Schema({
      name: {
        type: String,
        required: true,
      },
    });
    
    const Song = mongoose.model('Song', SongsInfo);
    
    // storage engine
    const storage = new GridFsStorage({
      url: mongoURI,
      file: (req, file) => new Promise((resolve, reject) => {
        crypto.randomBytes(16, (err, buf) => {
          if (err) {
            return reject(err);
          }
          const filename = buf.toString('hex') + path.extname(file.originalname);
          let fileInfo;
          if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
            fileInfo = {
              filename,
              bucketName: 'imageFiles',
            };
          } else {
            fileInfo = {
              filename,
              bucketName: 'songFiles',
            };
          }
          resolve(fileInfo);
        });
      }),
    });
    let upload;
    
    middleWare(app);
    
    app.post('/api/uploadSong', async (req, res) => {
      upload = multer({ storage }).any();
    
      upload(req, res, async (err) => {
        console.log('in');
        if (err) {
          return res.end('Error uploading file.');
        }
        const { name } = req.body;
        // push a Song into songs collection
        const songInfo = new Song({
          name,
        });
        songInfo.save((er, song) => {
          if (!er) {
            res.send('err');
          } else {
            console.log(err, song);
            res.send('err');
          }
        });
      });
    });
    

    At line (***) I used the same instance of mongoose that was initialized.. in the previous file I imported it again from the package...