#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)
новое количество: 300console.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.log3. Вам нужно добавить больше
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
.