View model callbacks onEvent* ignored on prototype chain

is it intentional that the onEvent* view model callbacks on the prototype chain are not called? As it is now they must be an own property of the object which is inconsistent with other callbacks such as onBeforeBinding etc.

Which onEvent callback is not working for you?

Is there a code example? Not a JavaScript expert, kinda know what the prototype chain would be but can't quite picture what that would look like.

1st example that shows the inconsistency:

class MyPlugin {
    onBeforeBinding() {
        // is called
    }

   onEventPositionUpdate(payload) {
      // is NOT called
   }
}
OCTOPRINT_VIEWMODELS.push({
    construct: MyPlugin,
    dependencies: [],
    elements: [],
});

2nd example with the onEvent* callback as an own property:

class MyPlugin {
    constructor() {
        this.onEventPositionUpdate = (payload) => {
            // is called
        };
    }
}
OCTOPRINT_VIEWMODELS.push({
    construct: MyPlugin,
    dependencies: [],
    elements: [],
});

This is probably an incompatibility with the class based way of writing it. OctoPrint's viewmodel handling code has been around longer than classes in JavaScript have, so it's entirely possible that there would have to be extra code written to add support for them.

Well it's not important that I use the class syntax. Just create an object and add the functions to the prototype and you will get the same result. The reason for this topic is the inconsistent behavior for different callbacks.

If someone is interested this is my workaround, which adds all onEvent* on the prototype as own properties.

Object.getOwnPropertyNames(Object.getPrototypeOf(this)).forEach((name) => {
    if (name.startsWith('onEvent') && typeof this[name] === 'function') {
        this[name] = Object.getPrototypeOf(this)[name];
    }
});

Ah right I understand the actual issue you're having now then. It's probably using a different way of calling them, since they are 'dynamic' rather than hardcoded - more events can be added by plugins etc.

I'll see if I can find the places in the source - I know roughly where they're being called from but I bet it is done differently, because the names are not constant.

Sorry for the huge delay in doing what was in reality a 30 second job since I knew what I was looking for anyway...

This is how the viewmodels are called for onEvent<event> handlers:

_.each(self.allViewModels, function (viewModel) {
    if (viewModel.hasOwnProperty("onEvent" + type)) {
        viewModel["onEvent" + type](payload);
    } 
});

Some code was removed to keep it concise, for some legacy versions of the callbacks

In comparison, the rest of the callbacks use if (_.isFunction(viewmodel[method])) { call it! }. So there's definitely a difference here, as one calls lodash.

I don't know why, but I guess this might help you.