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

3

8

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();
    })
  }

};
Sunwise answered 17/10, 2013 at 8:3 Comment(0)
H
2

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

Hebrew answered 4/12, 2013 at 17:4 Comment(1)
this doesn't explain how you can do it. They really should have built this in as far as I'm concerned, it's a super common use case.Urinal
F
2

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();
    })
  }

};
Fluvial answered 25/1, 2014 at 11:39 Comment(1)
Just noticed the question was a bit older, hope it still helps someone stumbling upon it like I did.Fluvial
T
1

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

Topdrawer answered 22/10, 2016 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.