Search code examples
javascriptnode.jscallbacknode-orm2

Nodejs ORM2 callback with parameters


I am creating models in the for statement:

  for (var j = 0; j < data.length; j++) {
        models.MyModel1.create({ name : data[j].name }, 
          function(err, model){
            if (err) {
              throw err
            }
            models.OtherMyModel.create({ model_id : model.id, index : j }], 
               function(err,submodule){
            });
        });
      }

So here I want to create submodel that will use parent model id and it's index j. And because of async var j will be data.length - 1 for all callback. How I can pass index parameter to the model creation callback?


Solution

  • You can use promises to achieve that.
    The following snippet uses when:

    var when = require('when');
    var nodefn = require('when/node/function');
    var promises = [];
    
    // Wrap model creation functions by a promise
    var createMyModel1 = nodefn.lift(models.MyModel1.create);
    var createOtherMyModel = nodefn.lift(models.OtherMyModel.create);
    
    for (var j = 0; j < data.length; j++) {
      // Store the index into a local variable because when the first promise
      // will resolve, `i` would be equal to `data.length`!
      var index = j;
    
      // Create the first model
      var promise = createMyModel1({
        name: data[j].name
      }).then(function(model) {
        // Once the model is created, create the submodel
        return createOtherMyModel({
          model_id: model.id,
          index: index
        });
      }, function(err) {
        throw err;
      });
    
      // Store the promise in order to synchronize it with the others
      promises.push(promise);
    }
    
    // Wait for all promises to be resolved
    when.all(promises).then(function() {
      console.log('All models are created');
    });
    

    Another solution is to use yield and any coroutine runner (available since node.js 0.11.x):

    var co = require('co');
    
    // Thunkify model creation functions
    var createMyModel1 = function(data) {
      return function(fn) { models.MyModel1.create(data, fn); };
    };
    
    var createOtherMyModel = function(data) {
      return function(fn) { models.OtherMyModel.create(data, fn); };
    };
    
    co(function *() {
      for (var j = 0; j < data.length; j++) {
        // Create first model
        var model = yield createMyModel1({
          name: data[j].name
        });
    
        // Create its submodel
        var submodel = yield createOtherMyModel({
          model_id: model.id,
          index: j
        });
      }
    })();