Search code examples
javascriptmongooseecmascript-6promisees6-promise

Promise, update parent scope variable


I have this code:

router.put('/test', (ctx, next) => {
  post.create(something, (err, newPost) => {
    if (err) return
    ctx.body = newPost
  })
  console.log(ctx.body) // => undefined
  ctx.status = 200
})

The problem is the value I set in the callback to the ctx.body variable is lose outside of the callback. And I fail to get it works. I tried bind/async await but without success. Can you help me ?

EDIT: @CertainPerformance, the "duplicate" post you linked does not answer my question because the solution it proposes includes to modify directly the signature of function which produces the promise post.create in my case. And I can't simply do that because it is part of Mongoose API. I read the entire post and I didn't found a solution. So what we do with this post?

EDIT: Based on the answer below, I found two solutions:

router.put('/test', async (ctx, next) => {
  const newPost = await Post.create(something).then(post => post)
  ctx.body = newPost
  ctx.status = 200
})

and

router.put('/test', async (ctx, next) => {
  const newPost = new Post(something)
  await newPost.save()
  ctx.body = newPost
  ctx.status = 200
})

Solution

  • Using async/await for example :

    createPromisified(data) {
      return new Promise((resolve, reject) => {
        post.create(data, (err, ret) => {
          if (err) return reject(err);
    
          return resolve(ret);
        });
      });
    }
    
    router.put('/test', async(ctx, next) => {
      await createPromisified(something);
    
      ctx.body = newPost;
     
      ctx.status = 200;
    })


    Using generic code example which represent your case :

    function postCreate(data, callback) {
      setTimeout(() => callback(false, 'ret'), 300);
    }
    
    function createPromisified(data) {
      return new Promise((resolve, reject) => {
        postCreate(data, (err, ret) => {
          if (err) return reject(err);
    
          return resolve(ret);
        });
      });
    }
    
    async function routerPut(ctx, next) {
      await createPromisified('something');
    
      console.log(ctx.body);
    
      ctx.body = 'newData';
    
      console.log(ctx.body);
    
      ctx.status = 200;
    }
    
    
    routerPut({
        body: 'hey',
      },
    
      () => {
        console.log('next');
      },
    );