Update route

A CRUD API is not complete with the update route! If you are a Hacker News frequenter, you'll know that titles of the submissions can change (but not the URL). This route should be straightforward, but there is one caveat! Yes, you could use findByIdAndUpdate, which is used by upvote, but what if you wanted to use Mongoose's instance method .save()?

Well, it does not return a Promise, so therefore we cannot yield to it. In fact, at the time of writing, there is still an open issue about this. Using save(), we can only use the traditional callback pattern. However, remember the rule—do not mix generator functions with callbacks!

So now what? Well, it will be quite common for certain node modules to be only available in the callback format. While most common modules are ported to a Koa version, you can still use Express packages; you just have to thunkify them. In fact, you could turn any callback style function into a thunk.

npm install --save thunkify

Now here's how to turn a function that accepts a callback into a yieldable thunk:

var thunk = require('thunkify'),

...

// Thunkify save method
Links.prototype.saveThunk = thunk(Links.prototype.save);

Adding the preceding code to model/links.js, we can now do the following in the update route:

app.put('/links/:id', function *(next) {
  this.assert((this.request.body.title || '').length > 0, 400, 'title is required'),

  var link;
  try {
    link = yield model.findById(this.params.id).exec();
  } catch (err) {
    if (err.name === 'CastError') {
      this.throw(400, 'invalid link id'),
    }
  }

  // Check that a link document is returned
  this.assert(link, 400, 'link not found'),

  link.title = this.request.body.title;
  link = yield link.saveThunk()[0];
  this.body = link;
});

Notice the use of saveThunk() near the bottom. It is basically a thunkified version of the original save() method. This means that an error that would originally be passed as the first argument in the callback is now thrown as an Error. We can afford not to wrap it in a try/catch block because the errorHandler middleware will catch it and throw a 500 error, which would be appropriate in this case.

Also, note how the thunk returns an array. This is because the original callback has an arity of 3. The first argument is the error, the second argument is the new document, while the third argument is the number of affected documents. The array returned by the thunk contains the latter two values. If the arity of the callback was 2, it would've just returned the value; something to keep in mind.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.188.121