Thanks marcel for you feedback, the article was wrote one year and half, so I need take time for remmember, nowdays most of people use npmjs.com/package/reflect-metadata. If you found why is not working or someidea leave a message or link to share, When return from my holidays I promise update the article.
I came up for a solution with this problem. One should set a value on the object themselves using a unique symbol rather than a value that is accessed on the prototype.
function Min(limit: number) {
return function(target: Object, propertyKey: string) {
const symbol = Symbol();
Object.defineProperty(target, propertyKey, {
get: function() {
return this[symbol];
},
set: function(newVal: string) {
if(newVal.length < limit) {
Object.defineProperty(target, 'errors', {
value: Your password should be bigger than ${limit}
});
}
else {
this[symbol] = newVal;
}
I came up for a solution with this problem. One should set a value on the object themselves using a unique symbol rather than a value that is accessed on the prototype.
function Min(limit: number) {
return function(target: Object, propertyKey: string) {
const symbol = Symbol();
Object.defineProperty(target, propertyKey, {
get: function() {
return this[symbol];
},
set: function(newVal: string) {
if(newVal.length < limit) {
Object.defineProperty(target, 'errors', {
value: Your password should be bigger than ${limit}
});
}
else {
this[symbol] = newVal;
}
I came up for a solution with this problem. One should set a value on the object themselves using a unique symbol rather than a value that is accessed on the prototype.
function Min(limit: number) {
return function(target: Object, propertyKey: string) {
const symbol = Symbol();
Object.defineProperty(target, propertyKey, {
get: function() {
return this[symbol];
},
set: function(newVal: string) {
if(newVal.length < limit) {
Object.defineProperty(target, 'errors', {
value: Your password should be bigger than ${limit}
});
}
else {
this[symbol] = newVal;
}
There is a reason where every instance of User class is having the same value for the password. The article author is binding the properties to the target argument in the decorator function. According to the docs the target parameter in the decorator function is the prototype of the class (in this case User.prototype). So when the author did Object.defineProperty(target, propertyKey, { get: getter, set: setter }), then the property is being bound to the User.prototype object and not the current object. Since, the property is defined on the prototype it is available to all the instances of that class.
For es2022 or above, useDefineForClassFields is default to be true.
This causes that the property of instance(new User()) is independent from its User.prototype.
To make this example work only, we should set "useDefineForClassFields":false.
This does not work. All instances of the User class do have the same value for Password! Here is an example: TypeScript Playground
Thanks marcel for you feedback, the article was wrote one year and half, so I need take time for remmember, nowdays most of people use npmjs.com/package/reflect-metadata. If you found why is not working or someidea leave a message or link to share, When return from my holidays I promise update the article.
any solution for this issue?
Hi Jose,
I came up for a solution with this problem. One should set a value on the object themselves using a unique symbol rather than a value that is accessed on the prototype.
function Min(limit: number) {
return function(target: Object, propertyKey: string) {
const symbol = Symbol();
Object.defineProperty(target, propertyKey, {
get: function() {
return this[symbol];
},
set: function(newVal: string) {
if(newVal.length < limit) {
Object.defineProperty(target, 'errors', {
value:
Your password should be bigger than ${limit}
});
}
else {
this[symbol] = newVal;
}
}
});
}
}
Hi Danny,
I came up for a solution with this problem. One should set a value on the object themselves using a unique symbol rather than a value that is accessed on the prototype.
function Min(limit: number) {
return function(target: Object, propertyKey: string) {
const symbol = Symbol();
Object.defineProperty(target, propertyKey, {
get: function() {
return this[symbol];
},
set: function(newVal: string) {
if(newVal.length < limit) {
Object.defineProperty(target, 'errors', {
value:
Your password should be bigger than ${limit}
});
}
else {
this[symbol] = newVal;
}
}
});
}
}
Hi Marcel,
I came up for a solution with this problem. One should set a value on the object themselves using a unique symbol rather than a value that is accessed on the prototype.
function Min(limit: number) {
return function(target: Object, propertyKey: string) {
const symbol = Symbol();
Object.defineProperty(target, propertyKey, {
get: function() {
return this[symbol];
},
set: function(newVal: string) {
if(newVal.length < limit) {
Object.defineProperty(target, 'errors', {
value:
Your password should be bigger than ${limit}
});
}
else {
this[symbol] = newVal;
}
}
});
}
}
There is a reason where every instance of User class is having the same value for the password. The article author is binding the properties to the target argument in the decorator function. According to the docs the target parameter in the decorator function is the prototype of the class (in this case User.prototype). So when the author did Object.defineProperty(target, propertyKey, { get: getter, set: setter }), then the property is being bound to the User.prototype object and not the current object. Since, the property is defined on the prototype it is available to all the instances of that class.
For es2022 or above,
useDefineForClassFields
is default to be true.This causes that the property of instance(
new User()
) is independent from itsUser.prototype
.To make this example work only, we should set
"useDefineForClassFields":false
.My example playground