0

I have an issue with querying my mongoose model and passing an altered object to the next promise chain.

The query does get passed to the next .then but without my newly assigned spaceTempName.

Any idea how to fix this issue?

  // promise - search for workspace ...
  var promise = Space.findOne( spaceId ).exec();

  promise.then( function ( space ) {

     return Stack.findOne( { _id: req.params.id }, function( err , stack ) {
          stack.spaceTempName = space.name;
          stack.name = 'test';

          console.log( stack );
          return stack;
      });
  })
  .then( function ( stack ) {

      console.log( stack );
  })
kyle
  • 691
  • 1
  • 7
  • 17
  • Possible duplicate of [How do I convert an existing callback API to promises?](https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) – Roamer-1888 Feb 16 '19 at 18:29
  • i really don't see how this is a duplicate question. – creativecoder Feb 16 '19 at 18:35
  • OK, it's not 100% clear without explanation. In short, returning a value from a nodeback has no effect. Returning a value from a `.then()` callback causes that value to the next `.then()` in the promise chain. So, in order to make the chain behave the way you want, `Stack.findOne()` needs to be "promisified" in the way described in case 3 of the reference. – Roamer-1888 Feb 16 '19 at 18:48
  • At least, that's the generalised way to approach the issue. The answer by Vadi suggests that omitting the nodeback causes `Stack.findOne()` to return a promise. If that is indeed so, then `Stack.findOne()` is already effectively promisified for you. Just omit the nodeback to get the desired behaviour. – Roamer-1888 Feb 16 '19 at 18:53

1 Answers1

1

You're using a callback here return Stack.findOne( { _id: req.params.id }, function, and return stack without changes for next then. You can get stack with changes only inside that callback, or by adding then after Stack.findOne:

// promise - search for workspace ...
var promise = Space.findOne( spaceId ).exec();

promise.then( function (space) {

  return Stack.findOne( { _id: req.params.id })
    .then(function (stack) {
      stack.spaceTempName = space.name;
      stack.name = 'test';

      console.log(stack);
      return stack;
    })
    .catch(function (err) { console.log(err) });
})
.then( function (stack) {

  console.log(stack);
})
.catch(function(err) { console.log(err) });

Or better for readability, you can put it into async function and use await:

const updateSpaceName = async (req, res) => {
  try {
    // promise - search for workspace ...
    promise = Space.findOne( spaceId ).exec();

    const space = await promise();

    const stack = await Stack.findOne( { _id: req.params.id } );

    stack.spaceTempName = space.name;
    stack.name = 'test';
    console.log( stack );

    // here you can pass stack to another promise
    // and it will have changed name
    await nextTestPromise(stack);

  } catch (err) {
    console.log(err);
  }
}
Vadi
  • 3,279
  • 2
  • 13
  • 30