I'm having two decorators. A class decorator and a method decorator. The class decorator defines metadata which I want to access in the method decorator.
ClassDecorator:
function ClassDecorator(topic?: string): ClassDecorator {
return (target) => {
Reflect.defineMetadata('topic', topic, target);
// I've also tried target.prototype instead of target
return target;
};
}
MethodDecorator:
interface methodDecoratorOptions {
cmd: string
}
function MethodDecorator(options: decoratorOptions) {
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
// HERE IS MY PROBLEM
console.log('metaData is: ', Reflect.getMetadata('topic', target));
}
}
And this is my Class definition:
@ClassDecorator('auth')
export class LoginClass {
@MethodDecorator({
cmd: 'login'
})
myMethod() {
console.log('METHOD CALLED');
}
}
THE PROBLEM:
The following line of the MethodDecorator returns metaData is: undefined
. Why is it undefined?
console.log('metaData is: ', Reflect.getMetadata('topic', target));
THE QUESTION:
How can I access the metadata defined by the ClassDecorator from the MethodDecorator?
The problem is the order in which decorators get executed. Method decorators are executed first, class decorators are executed after. This makes sense if you think about it, the class decorators need the complete class to act upon, and creating the class involves creating the methods and calling their decorators first.
A simple workaround would be for the method decorator to register a callback that would then be called by the class decorator after the topic was set: