Implementing JS decorator for chaining Class methods
Asked Answered
B

1

6

How could I implement a decorator that makes all methods of a class automatically chainable?

I have the following class:

class MyClass {
  async foo() { console.log(1); }
  async bar() { console.log(2); }
}

I want to be able to do the following:

@chainableMethods
class MyClass {
  ...
}

const myInstance = MyClass();

myInstance
  .foo()
  .bar();
Berube answered 19/2, 2019 at 1:58 Comment(0)
N
-1

You could try this

function chainableMethods (constructor) {
  let funcs = Object.getOwnPropertyNames(constructor.prototype);
  for (var i in funcs) {
    let func = funcs[i];
    let oldFunc = constructor.prototype[func];
    constructor.prototype[func] = (...args) => {
      let result = oldFunc.apply(this, args);
      return result || constructor.prototype;
      // Using 'result ||' for cases when a function does return something useful
      // You can remove it if it doesn't suit your requirement. 
    }
  }
}

If you intend on running bar only after the promise of foo is resolved then I don't think that will be possible.

Nonstandard answered 19/2, 2019 at 2:49 Comment(3)
I think you want result || this and you dont need the spread, just use arguments keyword.Actinouranium
Using the spread in case there are multiple arguments. Initially I did not have the result || but added it in case there is a function which returns something useful. In such cases it's better to have an error in the system than blindly chain the events.Nonstandard
This doesn't work. You cannot use an arrow function to create a (prototype) method, and you should not return the prototype object for chaining.Emeraldemerge

© 2022 - 2024 — McMap. All rights reserved.