Reputation: 19
I've seen this asked before but haven't found an answer. My function is clearly defined, I even put a breakpoint right before I call it and I checked it's 'typeof'.
Basically, I'm importing a utilites.js file to validate a result after find, and that validation function is called by various functions. For some it works, for others it throws an error. Can someone explain to me what's going on?
//Here is the file with the functions that use it: (below I'll add the utilities file)
const mongoose = require('mongoose');
const moment = require('moment');
const utilities = require('./utilities');
const models = require('../models/schemas');
const hash = require('object-hash');
const { Beverage, Purchase, Machine } = models;
const { ValidatedAfterFind, ValidatedAfterUpdate } = utilities;
const blueBirdPromise = require('bluebird');
mongoose.Promise = require('bluebird');
//THE VALIDATION FUNCTION WORKS HERE
const FetchBeveragePrice = (req, res) => {
const { beverageid } = req.params;
let beverage = '';
return Beverage.find({ _id: beverageid }).select('Price').exec()
.then(returnedBeverage => {
beverage = returnedBeverage[0]._doc;
if(ValidatedAfterFind(returnedBeverage, beverageid)) {
res.send({Price:beverage.Price})
}
else {
res.sendStatus(500)
}
})
}
const AddCoins = (req, res) => {
const { machineId, coinType } = req.body;
if (wrongCoinType(coinType)) {
return res.status(400).send("Wrong Coin Type")
}
Machine.updateOne({ _id: machineId }, { $inc: { fundsForCurrentPurchase: coinType, totalFunds: coinType } }).exec()
.then(results => {
if(ValidatedAfterUpdate(results, 1)){
res.sendStatus(200);
}
else {
res.sendStatus(500);
}
})
}
//THE VALIDATION FUNCTION DOESN'T WORK HERE
const GetBeverage = (req, res) => {
const { machineid, beverageid } = req.params;
return blueBirdPromise.join(Beverage.findById({ _id: beverageid }).exec(), Machine.find({ _id: machineid }).exec(),
(beverage, machine) => {
if (ValidatedAfterFind(beverage, beverageid) && ValidatedAfterFind(machine, machineid)) {
choosePurchaseProcessByConditions (machine, beverage, res)
}
else {
res.sendStatus(500)
}
})
}
function choosePurchaseProcessByConditions (machine, beverage, res) {
if (machine.beveragesInMachine[beverageid.toString()] > 0) {
if (machine.fundsForCurrentPurchase >= beverage.Price || machine.currentlyApprovedCreditCard) {
chooseStepsBeforePurchaseByBeverageType(machine, beverage, res);
}
else {
res.send(`Missing ${beverage.Price - machine.fundsForCurrentPurchase} shekels`);
}
}
else {
return res.send('Out of Stock');
}
}
function chooseStepsBeforePurchaseByBeverageType(machine, beverage, res) {
if (beverage.hot) {
if (machine.sugarUpdated) {
addPurchaseAndUpdateMachine(res, machine, beverage)
}
else {
return res.send("Choose Amount of Sugar")
}
}
else {
addPurchaseAndUpdateMachine(res, machine, beverage)
}
}
function addPurchaseAndUpdateMachine(res, machine, beverage) {
const newPurchase = new Purchase({ machineID: machine._id, creditCard: machine.currentlyApprovedCreditCard, price, creationDate: moment() });
const change = machine.fundsForCurrentPurchase - beverage.Price;
const updateBeveragesInMachine = `beveragesInMachine.${beverage._id.toString()}`;
const updateFieldsForMachine = {
$inc: {
totalFunds: -(machine.totalFunds - beverage.Price),
updateBeveragesInMachine: -1
},
fundsForCurrentPurchase: 0,
currentBeverage: '',
currentlyApprovedCreditCard: false,
sugarUpdated: false
}
return blueBirdPromise.join(newPurchase.save(), Machine.updateOne({ _id: machineid }, updateFieldsForMachine),
(purchaseResult, machineResult) => {
return blueBirdPromise.join(utilities.ValidationPromiseOnUpdate(purchaseResult, 1), utilities.ValidationPromiseOnUpdate(machineResult, 1),
() => res.json({ change }))
.catch(() => res.sendStatus(500))
})
}
module.exports = {
FetchBeveragePrice,
AddCoins,
GetBeverage
}
Here is the file with the validation functions:
const ValidatedAfterFind = ([result], searchedId) => result._doc._id.toString() === searchedId.toString();
const ValidatedAfterUpdate = (results, expectedModifications) => results.nModified === expectedModifications;
module.exports = {
ValidatedAfterFind,
ValidatedAfterUpdate
}
It's been driving me absolutely crazy, can't find the answer!
I thought it might have something to do with circular reference before but there isn't anything like that.
Any help would be much appreciated.
Thanks in advance.
Stack trace: Unhandled rejection TypeError: undefined is not a function at ValidatedAfterFind (c:\Users\Amir\Desktop\vending_machines\dal\utilities.js:16:28) at Beverage.findById.then.beverage (c:\Users\Amir\Desktop\vending_machines\dal\data.js:63:16) at tryCatcher (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\util.js:16:23) at Promise.module.exports.Promise._settlePromiseFromHandler (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\promise.js:512:31) at Promise.module.exports.Promise._settlePromise (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\promise.js:569:18) at Promise.module.exports.Promise._settlePromise0 (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\promise.js:614:10) at Promise.module.exports.Promise._settlePromises (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\promise.js:693:18) at Async._drainQueue (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\async.js:133:16) at Async._drainQueues (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\async.js:143:10) at Immediate.e.Async.drainQueues (c:\Users\Amir\Desktop\vending_machines\node_modules\bluebird\js\release\async.js:17:14) at runCallback (timers.js:672:20) at tryOnImmediate (timers.js:645:5) at processImmediate [as _immediateCallback] (timers.js:617:5)
Upvotes: 1
Views: 1486
Reputation: 23565
You can get this error when you are trying to destructure an object as it was an array.
My bet is that your error is here :
if (ValidatedAfterFind(beverage, beverageid) &&
ValidatedAfterFind(machine, machineid)) {
You should check beverage
and machine
there
const destructureMe = [
'a',
'b',
];
const destructureMeToo = {};
function func([ result ]) {
console.log(result);
}
func(destructureMe);
func(destructureMeToo);
Upvotes: 1