Как вычислить и вернуть новое количество для обновления в DB — NodeJS

#javascript #node.js #mongodb

#javascript #node.js #mongodb

Вопрос:

Я пытаюсь вычислить и вернуть a newQty , чтобы передать его для обновления в БД. Похоже, я получаю NaN for newQty . Дайте мне знать, что именно я делаю неправильно. Здесь вы найдете console.log :

  • console.log('order type:' orderType) тип заказа: Продать
  • console.log('new qty:' qty) новое количество: 300
  • console.log('old qty:' typeof oldQty) старое количество: объект
  • console.log('old qty:' oldQty.toString()) старое количество: { qtyPorfolio: 500 }
  • console.log('new qty after minus:' qty) новое количество после минуса: -300

JavaScript

 const fetchQtyPortfolio = async (arg) => {
  try {
    const query = { symbol: arg.symbol }
    const projection = { _id: 0 }

    const orderType = arg.orderType
    console.log('order type:'   orderType)// Sell

    let qty = arg.qty
    console.log('new qty:'   qty)// 300

    let oldQty = await Portfolio.find(query, projection).select("qtyPorfolio")
    console.log('old qty:'   typeof oldQty)// object
    console.log('old qty:'   oldQty.toString()) // {qtyPorfolio: 500}
    console.log('old qty:'   JSON.stringify(oldQty))//old qty:[{"qtyPorfolio":500}]

    if (isEmpty(oldQty)) {// false
      // Object is empty (Would return true in this example)
      console.log('new qty:'   qty)
      return qty
    } else {
      // Object is NOT empty
      if (orderType === 'Sell') qty = Math.abs(qty) * -1
      console.log('new qty after minus:'   qty)// -300
      const { qtyPorfolio } = oldQty//???
      console.log('qtyPorfolio :'   qtyPorfolio)// undefined
      console.log('qtyPorfolio :'   typeof qtyPorfolio)// undefined
      return newQty = qtyPorfolio   qty// ???
    }
  } catch (ex) {
    console.log(`fetchQtyPortfolio error: ${ex}`)
  }
}
  

Контроллер

 exports.postAddTransaction = async (req, res) => {
  const arg = req.body

  const qtyPorfolio = await portfolio.fetchNewQtyPortfolio(arg)
  console.log('quantity portfolio '   qtyPorfolio)//quantity portfolio NaN

  res.render('buysell')
}
  

Решение в соответствии с @Amir Wagner я изменил find(), который возвращал массив объектов, на findOne (), который возвращает только один объект

 const fetchQtyPortfolio = async (arg) => {
  try {
    const orderType = arg.orderType
    let qty = parseInt(arg.qty)

    const query = { symbol: arg.symbol }
    const projection = { _id: 0 }

    const oldQty = await Portfolio.findOne(query, projection).select("qtyPorfolio")
    //findOne returns the Object{} without the Array
    console.log('old qty:'   typeof oldQty)
    console.log('old qty:'   JSON.stringify(oldQty))

    if (isEmpty(oldQty)) {
      // Object is empty (Would return true in this example)
      return qty
    } else {
      // Object is NOT empty
      if (orderType === 'Sell') qty = Math.abs(qty) * -1
      const { qtyPorfolio } = oldQty
      return newQty = qtyPorfolio   qty
    }
  } catch (ex) {
    console.log(`fetchQtyPortfolio error: ${ex}`)
  }
}
  

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

1. Чтобы показать вам, что происходит, я отредактировал ваш вопрос, чтобы добавить console.log результаты в код. Так что, если newQty NaN это не происходит в коде, который вы опубликовали. Последняя строка вычисляет и возвращает 500 -300 = 200 , поэтому 200 возвращается как обещанное.

2. @DJDaveMark Я добавил контроллер, где я получаю NaN console.log

3. Вам нужно добавить больше console.log операторов, чтобы показать, какие значения у вас есть. Используйте JSON.stringify для объектов, подобных oldQty вместо toString() . И какую версию Node вы используете? Добавьте журнал, подобный этому: console.log(process.version);

4. Итак, проблема в том, что — isEmpty(oldQty) возвращает false, в то время как oldQty является объектом?

5. попробуйте изменить const { qtyPorfolio } = oldQty//??? to const { qtyPorfolio } = oldQty[0] oldQty — это массив, если вы хотите, чтобы объект, с которым он работает самостоятельно, был найден

Ответ №1:

В этом проблема

 const { qtyPorfolio } = oldQty
  

Просто сделайте

  qtyPorfolio = oldQty[0].qtyPorfolio;
  

Деструктурирование так не работает. Вы можете извлечь свойство из подобного объекта, но не из массива. Очевидно, что ваш oldQty — это массив с одним объектом.

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

1. Согласен с вами. функция find() возвращала массив объектов, поэтому я изменил ее на findOne(), которая возвращает только объект

Ответ №2:

Поскольку oldQty содержит [{"qtyPorfolio":500}] массив, вам просто нужно получить к нему доступ с помощью:

 const qtyPorfolio = oldQty[0].qtyPorfolio;
  

Если бы вы хотели использовать деструктурирование массива (я бы не стал), это было бы:

 const [firstResult] = oldQty
return newQty = firstResult.qtyPorfolio   qty
  

Но гораздо лучшим решением (которое вы нашли сами) было использовать findOne, который возвращает один документ, а не find .

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

1. Я только что изменил find (), который возвращал массив объектов, на findOne (), который возвращает только объект

2. Да, намного лучше. И если вы создадите слой DAO, в конце концов, это упростит ваш код. Я всегда создаю следующие уровни: презентация (экспресс), сервис (ваша бизнес-логика) и DAO (mongodb). Таким образом, код, который выполняет математику (сервис), не знает о том, откуда он берется (mongodb), это просто объект (ваша модель). Если вам нужно проанализировать / отформатировать даты для / из клиента, это работа уровня представления.

3. Я создаю свое первое приложение. Мне было интересно, можете ли вы взглянуть на мою архитектуру MVC. И приведите пример уровня DAO. Вот ссылка на github github.com/forza11879/nodeApp

4. Я буду отключен в течение следующих 24 часов, но я вернусь к вам в отношении вашего предложения уровня DAO

5. @JohnJohn Вот что я хотел бы сделать с разделением слоев: отдельные слои будут находиться в собственном файле, но все, что связано ( portfolio.route.js , portfolio.service.js , portfolio.dao.js , portfolio.test.js ), будет находиться в папке функций с именем portfolio (папка по функциям). Вызываемых папок не будет dao .