'use strict';
let mongodb = require('mongodb')
let mongoose = require('mongoose')
const fetch = require("node-fetch");
module.exports = function (app) {
mongoose.connect(process.env.DB, { useNewUrlParser: true, useUnifiedTopology: true })
let stockSchema = new mongoose.Schema({
name: { type: String, required: true},
likes: { type: Number, default: 0},
ips: [String]
})
let Stock = mongoose.model('Stock', stockSchema)
app.route('/api/stock-prices')
.get(function (req, res){
let responseObject = {}
let getPrice = (stock) => {
let api = `https://stock-price-checker-proxy.freecodecamp.rocks/v1/stock/${stock}/quote`
return fetch(api)
.then(response => response.json())
.then(data => {
return data['latestPrice']
})
}
let findStock = (stock) => {
return Stock.findOne({name: stock}, (err, stockDoc) => {
if (!err && stockDoc){
return stockDoc
}
})
}
let findStockAndUpdate = (stock, update) => {
return Stock.findOneAndUpdate({name: stock}, update, {new: true, upsert: true}, (err, updatedStock) => {
if (!err && updatedStock){
return updatedStock
}
})
}
let assign = (stockData, total_stock_num) => {
if (total_stock_num === 1){
responseObject['stockData'] = stockData
} else {
if (!responseObject['stockData']){
responseObject['stockData'] = []
}
responseObject['stockData'].push(stockData)
}
return responseObject
}
let buildResponse = (stock_name, total_stock_num, like_bool) => {
return findStock(stock_name).then(stockDoc => {
let stockData = {}
// if stock was liked
if (like_bool){
// if stock is found in DB and IP hasn't already liked stock
if (!stockDoc || !stockDoc['ips'].includes(req.ip)){
let update = { $inc: {likes: 1}, $push: {ips: req.ip} }
findStockAndUpdate(stock_name, update).then(updatedStock => {
getPrice(stock_name).then(price => {
stockData['stock'] = updatedStock['name']
stockData['price'] = price
stockData['likes'] = updatedStock['likes']
return assign(stockData, total_stock_num)
})
})
}
}
// if stock wasn't liked, or IP has already liked stock
if (!like_bool || (stockDoc && stockDoc['ips'].includes(req.ip))){
getPrice(stock_name).then(price => {
stockData['stock'] = stock_name
stockData['price'] = price
stockData['likes'] = stockDoc ? stockDoc['likes'] : 0
return assign(stockData, total_stock_num)
})
}
})
}
// if string, then only one stock was submitted
if (typeof (req.query.stock) === 'string'){
buildResponse(req.query.stock, 1, req.query.like).then(data => {
console.log(data) // returns undefined
})
// if array, both stocks were submitted
} else if (Array.isArray(req.query.stock)){
let stockArr = req.query.stock
buildResponse(stockArr[0], 2, req.query.like)
buildResponse(stockArr[1], 2, req.query.like)
}
});
};
Hi everyone,
Would anyone be able to explain to me why my console.log returns "undefined" instead of the object that was received from the buildResponse() function? If I log "assign(stockData, total_stock_num)" to the console from within the buildResponse() function, the response object appears fine, but it seems to get lost when I return it from buildResponse() to access it in the main part of my code.
question from:
https://stackoverflow.com/questions/66057090/promise-returns-undefined-despite-receiving-valid-data 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…