I'm looking to implement a class decorator called TopicClass
that will add both a property and a function to the decorated component. The catch is that the function needs to be able to access an injected Service. So, how can I achieve this?
So far, my attempts have been unsuccessful:
@Component({
selector: 'home',
styleUrls: ['./home.component.css'],
templateUrl: './home.component.html'
})
@TopicClass('home')
export class HomeComponent {
constructor(private topicService: TopicService) { }
}
The issue arises when trying to access the injected Service using the inserted function ngAfterViewInit
.
export function TopicClass(title: string) {
return function (target: Function) {
const original = target;
function construct(constructor, args) {
const c: any = function () {
return constructor.apply(this, args);
}
c.prototype = constructor.prototype;
const newInstance = new c();
newInstance['topic'] = new Topic(title, '');
newInstance['ngAfterViewInit'] = () => {
newInstance['topicService'].setTopic(newInstance['topic']);
}
return newInstance;
}
const ctor: any = (...args) => {
console.log("Service: " + original.prototype.topicService);
return construct(original, args);
};
ctor.prototype = original.prototype;
return ctor;
}
}
The problem lies in the fact that newInstance['topicService']
is undefined.
To test this scenario, I've set up a simple Angular project at: https://github.com/ptea/angular-class-decorator-test
You can find the service setup at: https://github.com/ptea/angular-class-decorator-test/blob/master/src/app/services/topic.service.ts
In an attempt to replicate the issue with a basic TypeScript program, I achieved the desired outcome:
newInstance['printStreet'] = () => {
console.log(`printFirstnameStreet: ${newInstance['firstname']}, ${newInstance['street']}`);
}
Here's the link to the TypeScript program: https://github.com/ptea/angular-class-decorator-test/blob/master/dashboard.ts
If you have any ideas or solutions to this dilemma, please share!