Decorators are a powerful feature of TypeScript that allow for efficient and readable abstractions when used correctly. In this lesson we will look at how we can use decorators to initialize properties of a class to promises that will make GET requests to certain URLs. We will also look at chaining multiple decorators to create powerful and versatile abstractions.
Inside @First decorator, prevInit() should be prevInit.call(target). Otherwise, value of "this" inside getter of @Get decorator will be undefined.
Yes. There is truble with context into @First decorator. Could you please make changes to your lesson?
That's a very good point, Anup! Thank you for pointing that out!!
I updated the lesson code on GitHub to correct for this. It's also slightly different than your suggestion:
function First() {
return function(target: any, name: string) {
const hiddenInstanceKey = "_$$" + name + "$$_";
const prevInit = Object.getOwnPropertyDescriptor(target, name).get;
const init = (prevInit: () => any) => {
return prevInit()
.then(response => response[0]);
};
Object.defineProperty(target, name, {
get: function() {
return this[hiddenInstanceKey] || (this[hiddenInstanceKey] = init(prevInit.bind(this)));
},
configurable: true
});
}
}
Reason for this is that in your example, target
will actually refer to the constructor of our service, and not the actual instance. And we need them to reffer to the same instance always inside our get
s, so we can store our promise, and re-use it correctly.