Correct way to use before save hooks on mongoose.js

Problem

I'm trying to put together a before save callback on my Mongoose model. The callback is suppose to make a GET request to an API and save the response to a field of the object. Due to the nature of node.js of it being async and the save happening before the request is done. What would be the correct way of performing such operation?

Right now I'm doing the following:

Schema.pre('save', function(next){
  self = this
  request.get('myapi.com/method', { param_one: this_is_myparam } , function(err, data){
    self.myField = data['myFrield']
    self.save()
    next()
  }
  next()
})

Am I doing the right thing? Or is there a more JavaScript/Node way of doing things?

Problem courtesy of: Gotjosh

Solution

That looks right but remove the self.save() line, which will cause an unnecessary duplicate save. You just need to modify this during the preSave hook and then mongoose will do the actual save to mongodb for you.

Schema.pre('save', function(next){
  //Yes, good. `this` here will be your mongoose model instance
  self = this
  request.get('myapi.com/method', { param_one: this_is_myparam } , function(err, data){
    //Yes, good. All you have to do here is CHANGE the mongoose model instance
    self.myField = data['myFrield']
    //No, bad. This is extraneous. By definition, mongoose is going to save your model
    //automatically after the "preSave" hook completes, so you should remove this.
    //self.save()
    next()
  }
  //No, bad. Remove this as well. You need to wait for the response to come back
  //next()
})
Solution courtesy of: Peter Lyons

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.