Ошибка типа: невозможно прочитать свойство 'imageName' из неопределенного - PullRequest
0 голосов
/ 04 сентября 2018

Я практикую создание restful API с помощью node.js с использованием MongoDB. У меня есть маршрутизатор, который отправляет запрос на удаление router.delete. Внутри router.delete у меня есть две операции. Первый - найти и выбрать productImage в соответствии с заданным идентификатором, а с помощью fs.unlinkSync удалить загруженный файл на физическом жестком диске. Вторым является удаление записи базы данных по идентификатору. если я так поступаю, я получаю сообщение об ошибке и просто удаляю запись базы данных.

TypeError: Невозможно прочитать свойство 'productImage' с нулевым значением в Product.findById.select.exec.then.docs

Если я создам два разных route.delete, я просто смогу управлять физическим удалением. Как я могу сделать обе операции одновременно?

Вот мой код:

Router.delete('/:productId', checkAuth, (req, res, next) => {
const id = req.params.productId;
var imageName = "";

Product.findById(id)
    .select('productImage')
    .exec()
    .then(docs => {
        imageName = docs.productImage;
        fs.unlinkSync(__rootdir + "\\" + imageName);
        console.log(doc.productImage);
    })
    .catch(err => {
        console.log(err);
        res.status(500).json({
            error: err
        });
    });

Product.deleteOne({_id: id})
    .exec()
    .then(result => {
        res.status(200).json({
            message: 'Product Deleted',
            request: {
                type: 'POST',
                url: 'http://localhost:3000/products/', 
                body: {name: 'String', price: 'Number', productImage: 'String'}
            }
        });
    })
    .catch(err => {
        console.log(err);
        res.status(500).json({
            error: err
        });
    });    
});

1 Ответ

0 голосов
/ 04 сентября 2018

Кажется, что документ, который вы пытаетесь найти (и выберите некоторые поля), уже удален второй частью вашего кода. (Это возможно, потому что все эти операции асинхронные). Не уверен, что это лучшее решение, но я рекомендую вам удалить документ только после того, как он был найден, и его productImage был успешно получен, а fs unlink запущен.

Router.delete('/:productId', checkAuth, (req, res, next) => {
  const id = req.params.productId;
  var imageName = "";

  Product.findById(id)
    .select('productImage')
    .exec()
    .then(docs => {
      imageName = docs.productImage;
      fs.unlinkSync(__rootdir + "\\" + imageName);
      console.log(docs.productImage); // by the way you had misspell here
      return Product.deleteOne({_id: id}).exec();
    })
    .then(() => {
      res.status(200).json({
        message: 'Product Deleted',
        request: {
          type: 'POST',
          url: 'http://localhost:3000/products/',
          body: {
            name: 'String',
            price: 'Number',
            productImage: 'String'
          }
        }
      });
    })
    .catch(err => {
      console.log(err);
      res.status(500).json({
        error: err
      });
    });
});

P.S. Я также рекомендую не использовать метод unlinkSync, потому что синхронные операции блокируют поток. Я бы предпочел использовать fs.unlink.

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