Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call a model instance method in lifecycle callback in Sails/Waterline?

I have set up a simple model with 2 instance methods. How can I call those methods in lifecycle callbacks?

module.exports = {

  attributes: {

    name: {
      type: 'string',
      required: true
    }

    // Instance methods
    doSomething: function(cb) {
      console.log('Lets try ' + this.doAnotherThing('this'));
      cb();
    },

    doAnotherThing: function(input) {
      console.log(input);
    }

  },

  beforeUpdate: function(values, cb) {
    // This doesn't seem to work...
    this.doSomething(function() {
      cb();
    })
  }

};
like image 319
ragulka Avatar asked Oct 17 '13 08:10

ragulka


3 Answers

It looks like custom defined instance methods were not designed to be called in lifecycle but after querying a model.

SomeModel.findOne(1).done(function(err, someModel){
   someModel.doSomething('dance')
});

Link to example in documentation - https://github.com/balderdashy/sails-docs/blob/0.9/models.md#custom-defined-instance-methods

like image 177
Paweł Wszoła Avatar answered Oct 19 '22 14:10

Paweł Wszoła


Try defining the functions in regular javascript, this way they can be called from the entire model file like this:

// Instance methods
function doSomething(cb) {
  console.log('Lets try ' + this.doAnotherThing('this'));
  cb();
},

function doAnotherThing(input) {
  console.log(input);
}

module.exports = {

  attributes: {

    name: {
      type: 'string',
      required: true
    }
  },

  beforeUpdate: function(values, cb) {
    // accessing the function defined above the module.exports
    doSomething(function() {
      cb();
    })
  }

};
like image 23
danba Avatar answered Oct 19 '22 15:10

danba


doSomething and doAnotherThing aren't attributes, are methods and must be at Lifecycle callbacks level. Try something like this:

module.exports = {

    attributes: {

        name: {
            type: 'string',
            required: true
        }

    },

    doSomething: function(cb) {
        console.log('Lets try ' + "this.doAnotherThing('this')");
        this.doAnotherThing('this')
        cb();
    },

    doAnotherThing: function(input) {
        console.log(input);
    },

    beforeCreate: function(values, cb) {

        this.doSomething(function() {
            cb();
        })
    }

};

On Second place, you're trying send to console this.doAnotherThing('this') but it is an instance of model so you can't pass it like parameter on the "Lets try" string. Instead of it try to exec this function apart and will work

like image 41
crlsmtzprds Avatar answered Oct 19 '22 14:10

crlsmtzprds