malcoauri
malcoauri

Reputation: 12209

Node.js promisses chaining

There is the following code:

router.put('/:id', function(req, res) {
  models.Task.find(req.params.id).then(function(task) {
    task.updateAttributes({
      title: req.body.title,
      description: req.body.description
    }).then(function(task) {
      res.json(task);
    })
  });
});

I'm trying to re-factor this code following way:

router.put('/:id', function(req, res) {
  models.Task.find(req.params.id).then(function(task) {
    task.updateAttributes({
      title: req.body.title,
      description: req.body.description
    })
  }).then(function(task) {
    res.json(task);
  });
});

In the first case I can see correct JSON output, but in the second can I see empty output. Why?

Upvotes: 2

Views: 50

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1075925

You're not waiting for updateAttributes to complete anymore. You can do, though, by just adding a return:

router.put('/:id', function(req, res) {
  models.Task.find(req.params.id).then(function(task) {
    return task.updateAttributes({
//  ^^^^^^
      title: req.body.title,
      description: req.body.description
    });
  }).then(function(task) {
    res.json(task);
  });
});

When you return a promise from an earlier handler in the chain, subsequent handlers wait for it (and receive its resolution value).


Side note: Remember to handle failures in promises, too, by using the second argument to then and/or using catch.

Upvotes: 3

PiniH
PiniH

Reputation: 1941

You need to return the 2nd promise:

router.put('/:id', function(req, res) {
  models.Task.find(req.params.id).then(function(task) {
    return task.updateAttributes({
      title: req.body.title,
      description: req.body.description
    });
  }).then(function(task) {
    res.json(task);
  });
});

Upvotes: 2

Related Questions