With a custom decorator I want inject into a method a property with another method inside. The decorator:
function test() {
return function(target, key, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
Object.defineProperty(this, "foo", {
value: () => console.log("foo fired!"),
enumerable: false,
writable: false
});
return originalMethod.apply(this, args);
};
return descriptor;
};
}
usage:
import { Component} from "@angular/core";
@Component({
selector: "my-app",
template: `<button (click)="bar()">Test</button>`,
})
export class AppComponent {
@test()
bar() {
console.log("bar fired!");
const self = this;
(self as any).foo(); // this works!
(this.bar as any).foo(); // this doesn't works!
}
}
see online https://stackblitz.com/edit/angular-ivy-dhfasr?file=src%2Fapp%2Fapp.component.ts
I don't understand because this works:
@test()
bar() {
const self = this;
(self as any).foo();
}
but this doesn't works (Error: this.bar.foo is not a function):
@test()
bar() {
(this.bar as any).foo(); // Error: this.bar.foo is not a function
}
what I'm doing wrong?
inside of bar
function when you call it this
keyword references to AppComponent instance. it is expected that you added foo
element to AppComponent when you call bar
method.
if you still want to access it like (this.bar as any).foo();
then define foo field on a bar
, not this
function test() {
return function(target, key, descriptor) {
const originalMethod = descriptor.value; // no point of overriding it. we just add a field
Object.defineProperty(originalMethod, "foo", {
value: () => console.log("foo fired!"),
enumerable: false,
writable: false
});
return descriptor;
};
}