Почему эта экспортированная функция Gridfs не выполняется правильно?

#javascript #node.js #gridfs-stream

#javascript #node.js #gridfs-stream

Вопрос:

Я работаю над приложением React с серверной частью node и mongo. Серверная часть mongo будет хранить изображения с использованием Gridfs-stream. Я успешно реализовал сохранение изображений, но теперь у меня возникают проблемы с извлечением определенных изображений из базы данных.

Функция для gfs.files.findOne работала корректно, пока я не переместил ее в отдельный файл и не добавил в модуль экспорта. Я не могу понять, что может быть причиной сбоя при выполнении.

Получение изображения в database.js:

 exports.getFile = (filename) => {
  console.log('loading file: '   filename);
  gfs.files.findOne({ filename : filename }, (err, file) => {
    console.log('finding file');
    if (file) {
      // checking specifically for image here
      if (file.contentType == 'image/png' || file.contentType == 'image/jpeg') {
        res.set('Content-Type', file.mimetype);
        const readstream = gfs.createReadStream(file.filename);
        console.log('returning readstream');
        return readstream; 
      }
      else {
        console.log('error loading');
        const err = { "status": "error", "details": "File is not an image" };
        return err;
      }
    }
    else {
      console.log('error loading');
      const err = { "status": "error", "details": "Failed to find specified file" };
      return err;
    }
  });
  console.log('function ending');
}
  

Вызов функции в маршруте api users.js:

 let rs = database.getFile(pic.profilePicture);
if (rs.status amp;amp; rs.status === "error") {
    res.json(rs);
}
else {
    // we have a readstream
    rs.pipe(res);
}
  

Консольный вывод в терминале:

 [0] testing retrieving profile picture
[0] loading file: 7be7c6a99a96023763b753febd85a92e.png
[0] function ending
[0] events.js:173
[0]       throw er; // Unhandled 'error' event
[0]       ^
[0] 
[0] TypeError: Cannot read property 'status' of undefined
[0]     at User.getProfilePicture (/Users/zachdobbs/Documents/Projects/Better/routes/api/users.js:44:20)
[0]     at /Users/zachdobbs/Documents/Projects/Better/node_modules/mongoose/lib/model.js:4698:16
[0]     at /Users/zachdobbs/Documents/Projects/Better/node_modules/mongoose/lib/query.js:4099:12
[0]     at process.nextTick (/Users/zachdobbs/Documents/Projects/Better/node_modules/mongoose/lib/query.js:2681:28)
[0]     at processTicksAndRejections (internal/process/next_tick.js:74:9)
[0] Emitted 'error' event at:
[0]     at /Users/zachdobbs/Documents/Projects/Better/node_modules/mongoose/lib/model.js:4700:13
[0]     at /Users/zachdobbs/Documents/Projects/Better/node_modules/mongoose/lib/query.js:4099:12
[0]     at process.nextTick (/Users/zachdobbs/Documents/Projects/Better/node_modules/mongoose/lib/query.js:2681:28)
[0]     at processTicksAndRejections (internal/process/next_tick.js:74:9)
[0] [nodemon] app crashed - waiting for file changes before starting...
  

Насколько я могу видеть, функция gfs.files.findOne пропускает весь блок и переходит прямо к концу функции. Отображаются только выходные данные loading file: ...png и function ending . Эти журналы находятся в начале и конце функции, но ни один из других журналов внутри функции не выполняется. Я не могу понять, почему это может быть так. Если кто-нибудь может помочь мне решить эту проблему, я был бы очень признателен.

Комментарии:

1. разве вы не должны возвращать ее как объект? { статус: «ошибка», подробности: «Не удалось найти указанный файл»}; вы возвращаете Json позже, вы можете использовать JSON.stringify для отправки его клиенту или что-то еще.

2. @jcuypers Я полагаю, что да, но внесение этого изменения не приводит к изменению какого-либо результата. Блоки if..else кода в database.js судя по выводам журнала, они даже не пострадали

3. Пожалуйста, распечатайте err сразу после строки gfs: gfs.files.findOne({ filename : filename }, (err, file) => {

4. @jcuypers добавление console.log(ошибка) сразу после этой строки ничего не меняет. Журналы по-прежнему выводят только loading file: ... и function ending . Я не могу получить какие-либо журналы для печати из фактического gfs.files.findOne() блока

5. хорошо, странно. извините, я использую mongoose-gridfs. просто проверяю руководство для gridfs-stream. Все примеры формы var gfs = Grid(conn.db); gfs.files.find({ filename: 'myImage.png' }).toArray(function (err, files) { if (err) ... console.log(files); }) в качестве альтернативы вы можете использовать ГФС.findOne-стенография, чтобы найти один файл gfs.findOne({ _id: '54da7b013706c1e7ab25f9fa'}, function (err, file) { console.log(file); }); findOne, похоже, нет . Файлы. в названии. вы уверены в команде

Ответ №1:

Вот так:

 exports.getFile = (filename) => {
  console.log('loading file: '   filename);
  gfs.findOne({ filename : filename }, (err, file) => {
    console.log('finding file');
    if (file) {
      // checking specifically for image here
      if (file.contentType == 'image/png' || file.contentType == 'image/jpeg') {
        res.set('Content-Type', file.mimetype);
        const readstream = gfs.createReadStream(file.filename);
        console.log('returning readstream');
        return readstream; 
      }
      else {
        console.log('error loading');
        const error = { status: "error", details: "File is not an image" };
        return error;
      }
    }
    else {
      console.log('error loading');
      const error = { status: "error", details: "Failed to find specified file"   err };
      return error;
    }
  });
  console.log('function ending');
}
  

и затем:

 let rs = database.getFile(pic.profilePicture);
if (rs.status amp;amp; rs.status === "error") {
    res.json(JSON.stringify(rs));
}
else {
    // we have a readstream
    rs.pipe(res);
}