1

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)

4
  • Can you post error stacktrace ? Commented Aug 30, 2018 at 14:55
  • Yep, here it is: Commented Aug 30, 2018 at 14:57
  • [result] this might be the issue inside your ValidatedAfterFind function. Either check for undefined inside the method or change that argument to non-array Commented Aug 30, 2018 at 15:06
  • Thanks a lot Kashif! It worked. Commented Aug 30, 2018 at 16:02

1 Answer 1

1

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);

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I didn't pay attention to the fact that in the second function I used findById, which returns an object. Anyway, I really appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.