Добавить метаданные в файл GridFS через request.body - PullRequest
0 голосов
/ 15 апреля 2019

У меня возникла небольшая проблема при попытке динамически обновить свойство metadata в экспортированном модуле Multer GridFS. Этот модуль содержит «механизм загрузки», который обрабатывает загрузку файлов в мою базу данных. Это библиотека multer-gridfs-storage.

Вот мой модуль загрузки GridFs gridFs_upload_engine.js:

> //Upload Engine 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; 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: (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',
>           metadata: 'Add Metadata here'
>         };
>         resolve(fileInfo);
>       });
>     });   } });
> 
> const uploadEngine = multer({ storage });
> 
> module.exports = {   engine: uploadEngine,   gfs };

Свойство metadata выше - это то, что мне нужно изменить. Этот fileinfo объект добавляется GridFs к каждому файлу при загрузке. Параметр req - это место, где я думал, что смогу получить доступ к req.body маршрута, который вызвал это промежуточное ПО, но он возвращается как undefined.

Вот мой тестовый маршрут:

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

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

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

const { engine } = upload;
//Upload Single File
router.post(
  '/single',
  engine.single('file'),
  upload_controller.upload_single_file
);

Здесь я передаю промежуточное ПО GridFs в мой маршрут API. Это позволяет контроллеру использовать это.

Это мой upload controller:

exports.upload_single_file = (req, res, next) => {
  console.log({ file: req.file });
  res.redirect('/');
};

console.log выводит информацию о файле, который был загружен с помощью механизма загрузки GridFs, как и ожидалось.

Я знаю, что мне нужно каким-то образом передать параметр в gridFs_upload_engine.js. Поскольку этот файл является экспортированным модулем, я не совсем уверен, как это сделать. Я могу поместить этот код непосредственно в мой контроллер API и сделать так, но я хочу, чтобы это был модуль, который я могу вызывать с других контроллеров.

1 Ответ

0 голосов
/ 15 апреля 2019

Я решил эту проблему, открыв функцию, которая позволяет мне обновлять переменную, которая затем используется в качестве значения metadata.

Маршрут API:

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

const { engine, updateMetadata } = upload;

//Upload Single File
router.post(
  '/single',
  (req, res, next) => {
    updateMetadata('xxxxxx'); //Static test value
    next();
  },
  engine.single('file'),
  upload_controller.upload_single_file
);

Здесь,Я добавил обратный вызов, который содержал открытую функцию updateMetadata() из механизма загрузки.Здесь я устанавливаю metadata с открытой функцией updateMetadata().После этого, используя next(), router перемещается на engine.single('file'), что фактически обрабатывает загрузку файла.

Вот механизм загрузки GridFs:

//Create Storage Engine
let updatedMetadata;

const updateMetadata = id => {
  updatedMetadata = id;
};

const storage = new GridFsStorage({
  url: mongoDb,
  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',
          metadata: updatedMetadata ? updatedMetadata : null
        };
        resolve(fileInfo);
      });
    });
  }
});

const uploadEngine = multer({ storage });

module.exports = {
  engine: uploadEngine,
  updateMetadata,
  gfs
};

Я не уверен, что это лучший способ сделать это, но он работает должным образом и, как и ожидалось, поэтому я не собираюсьдопросить это дальше.Надеюсь, это кому-нибудь поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...