简体   繁体   中英

How can I pass options into an imported module?

I have a utility module that creates an instance of a multer-gridfs storage engine for uploading files to my Mongo database. I use this module inside of any API route that requires the need to upload files.

I need to be able to update the metadata property value with a unique identifier. More than likely this will be the mongoose _id of the user uploading the file, but for now I am not concerned with that aspect of it. I really just want to know if I can change the metadata property dynamically.

Here is the storage engine gridFs_upload_engine.js :

const mongoose = require('mongoose');
const path = require('path');
const crypto = require('crypto');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');

//Init Upload Engine
let gfs;
//Global instance of the DB connection
const database = mongoose.connection;
const mongoDb = process.env.MONGODB_URI || process.env.MLAB_URL;

database.once('open', () => {
  //Init Stream
  gfs = Grid(database.db, mongoose.mongo);
  gfs.collection('uploads');
});

//Create Storage Engine
const storage = new GridFsStorage({
  url: mongoDb,
  file: (res, 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',
          metadata: 'NEED TO UPDATE THIS'
        };
        resolve(fileInfo);
      });
    });
  }
});

const uploadEngine = multer({ storage });

module.exports = {
  uploadEngine,
  gfs
};

Above you can see the metadata property that I need to be able to dynamically change with some undetermined unique identifier. Is it possible to do that with an exported file?

Here is how I am utilizing it inside of an API route:

const express = require('express');
const router = express.Router();

//Controllers
const upload_controller = require('../../controllers/uploader');

//Utilities
const upload = require('../../utils/gridFs_upload_engine');

const { uploadEngine } = upload;

//Upload Single File
router.post(
  '/single',
  uploadEngine.single('file'),
  upload_controller.upload_single_file
);

//Upload Multiple Files
//Max file uploads at once set to 30
router.post(
  '/multiple',
  uploadEngine.array('file', 30),
  upload_controller.upload_multiple_files
);

module.exports = router;

I pass the uploadEngine into the API route here, so that the route controller can use it, and that works with no issue. I am just having quite a time trying to figure out how to update metatdata dynamically and I am leaning towards my current implementation not allowing for that.

I don't know much about node and have now idea what multer-gridfs is but I can answer How can I pass options into an imported module?

You can export an function that returns another function. And you would import it like

const configFunction = require('nameoffile')
// this returns a functions with the config you want
const doSomethingDependingOnTheConfig = configFunction({...someConfig}) 

And in the file you are importing you would have a function returning another function like

const configFunction = ({...someConfig}) => (your, func) => {

    // do what you want deppending on the config

}

module.exports = configFunction

I know this doesn't answer your question the way you want, but answer you question title and I hope this give you a better understanding of how to do what you want to do.

If this doesn't help, just let me know.

You would need to pass a parameter to the module gridFs_upload_engine.js and do the magic there.

An example could be:

In gridFs_upload_engine.js file:

function uploadEngine (id, file) {
  // update what you want
}

module.exports = {
  ...
  uploadEngine: uploadEngine
}

In your router:

const upload = require('../../utils/gridFs_upload_engine')
...

router.post('/single/:id', function(req, res, next) {
  ...
  upload.uploadEngine(req.params.id, file)
  next()

}, upload_controller.upload_single_file)

In other words, when you are exposing gfs and uploadEngine inside your module, you could instead expose a function that would receive the arguments needed to perform the upload.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM