"Implicit" meteor methods on my object?


#1

This might sound strange, but I have a class. When I create the class, I want to generate a lot of meteor methods.

Robot = class RobotServer extends RobotBase {
  // ... not terribly important
  // want to make this run as if it were a meteor method
  send(command) {
    if (Roles.userIsInRole(this.userId, 'operator', this._id)) {
      this._sockets.get('commands').write(`${command}\r`);
    }
  }
}

I want to expose this as if it were a meteor method. That is to say, on my client, I can do something like:

Baymax = new Robot();
Baymax.send('message "I am Baymax, your personal health care companion"', function (err, result) {
  console.log('command successfully sent.')
});

Is this possible within meteor?


#2

You can share the code of the class. Then you can make a single Meteor method: robotFunction. And then in your class you can do something like:

// pseudo code example
Robot = class Robot {
  constructor() {
    console.log('robot initiated');
  }
  execute(command, callback) {
    if(Meteor.isClient){
      Meteor.call('robotFunction', command, callback);
    }else{
      // do the server side thing here
      this._sockets.get('commands').write(`${command}\r`);
      console.log('server command active')
    }
  }
  drive() {
    this.execute('drive', function(error, result) {
      if(error) {
        console.log('oops crashed')
      }else{
        console.log('yeah I am driving')
      }
    });
  }
}
Meteor.methods({
  robotFunction: function(command) {
    let Robby = new Robot();
    if(command === 'drive') {
      Robby.drive();
    }
  }
})
// on the client
let Robby = new Robot();
Robby.drive(); // should show "yeah I am driving" on client and "server command active" on server
// on the server you can do the same
let Robby = new Robot();
Robby.drive(); // should show "yeah I am driving" and "server command active" both on server