6

I'm new to promises and think I may be mixing up what gets returned from promises and passed around to .then and .catch blocks. I get a TypeError on the commented line below, but when I change it from

.then(Promise.resolve)

to .then((obj) => { Promise.resolve(obj); })

The error disappears. What's the difference here? Am I misunderstanding something about how promises should be chained?

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.set('debug', true);
var FoodItem = require('../models/FoodItem.js');
var UserFoodItem = require('../models/UserFoodItem.js');
var User = require('../models/User.js');

var StockController = {};
StockController.createUserFoodItem = function(userId, {name, qty}) {
    var userItem = new UserFoodItem({
        user: new mongoose.Types.ObjectId(userId),
        dateAdded: new Date(),
        quantity: qty
    });

    return new Promise((resolve, reject) => {
        FoodItem.findOne({ 'name': name })
            .then((foodItem) => {
                if (foodItem) {
                    userItem.foodItem = foodItem; 
                    userItem.save().then((userFoodItem) => {
                        resolve(userFoodItem);
                    });
                } else {
                    reject(new Error('No food item yet!'))
                }
            });
    });
}

StockController.addFoodItemToFridge = function (userId, {name, qty}) {
    return StockController.createUserFoodItem(userId, {name, qty})
        .then((userFoodItem) => {
            User.findByIdAndUpdate(userId, 
                { $push: { "fridge": userFoodItem }},
                { new: true }
            ).then(Promise.resolve) // ERROR OCCURS HERE
            .catch(console.log);
       })
        .catch(console.log("hello"));
}

The error:

TypeError: function resolve() { [native code] } called on non-object
    at resolve (native)
    at tryCatcher (/Users/jessy/herb/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/Users/jessy/herb/node_modules/bluebird/js/main/promise.js:507:31)
    at Promise._settlePromiseAt (/Users/jessy/herb/node_modules/bluebird/js/main/promise.js:581:18)
    at Promise._settlePromises (/Users/jessy/herb/node_modules/bluebird/js/main/promise.js:697:14)
    at Async._drainQueue (/Users/jessy/herb/node_modules/bluebird/js/main/async.js:123:16)
    at Async._drainQueues (/Users/jessy/herb/node_modules/bluebird/js/main/async.js:133:10)
    at Immediate.Async.drainQueues (/Users/jessy/herb/node_modules/bluebird/js/main/async.js:15:14)
    at runCallback (timers.js:651:20)
    at tryOnImmediate (timers.js:624:5)
    at processImmediate [as _immediateCallback] (timers.js:596:5)
Jess
  • 1,515
  • 3
  • 23
  • 32
  • `.resolve` is a *method* and needs to be bound to a context when called – Bergi Jul 08 '17 at 18:48
  • 1
    You *never* need to pass `Promise.resolve` as a callback to `.then()`, that's [as pointless as the identity function](https://stackoverflow.com/q/41089122/1048572). Also, avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) in `createUserFoodItem`! – Bergi Jul 08 '17 at 18:49

0 Answers0