I have a decorator that casts a string number to a javascript number.
Example: "87"
-> 87
.
The code is quite simple:
function digit(target: any, key: string) {
// property value
var _val = this[key];
// property getter
var getter = () => _val;
// property setter
var setter = (newVal) => _val = parseInt(newVal)
// Create new property with getter and setter
Object.defineProperty(target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true,
});
}
class User {
@digit
public id: number;
public isActive: boolean;
constructor(instanceData) {
this.id = instanceData.id;
this.isActive = instanceData.isActive;
}
}
let user = new User({
id: '712',
isActive: '1'
})
console.log([user.id]) // [ 712 ] as expected
console.log(user) // Person { isActive: '1' }
Why doesn't the id field appear in the second console.log and how can I make it appear ? I can access it but it's hidden in the console.
Thanks !
Because a property decorator for an instance property is applied to the prototype of the class, not to any instance. That is the best you can do because no instance of User
exists before you call new User()
. When you just use console.log()
to get debug output you only see the instance's own properties, not the ones on the prototype.
Since all instances share a prototype, you probably don't want to do it this way:
let user = new User({
id: '712',
isActive: '1'
})
let user2 = new User({
id: '567',
isActive: '1'
})
console.log(user.id) // 567!
One prototype, one id
value for the whole class. All User
objects have the same id
. Oops.
You probably want to at least do something to instances when they are available:
function digit(target: any, key: string) {
// Create new property with getter and setter
Object.defineProperty(target, key, {
get: function () { return this._val },
set: function (newVal) { this._val = parseInt(newVal) },
enumerable: true,
configurable: true,
});
}
Notice the use of this
inside the get
and set
methods. That puts the _val
property on the instance, so you'll get distinct ones. You will still not see id
via console.log()
, (and you will see _val
).
There are too many ways to configure the object so that it prints out what you expect with console.log()
and behaves the way you expect (one id
per instance) for me to enumerate here. As one hint: you could put the property accessor on the instance by modifying the class constructor instead of trying to use a decorator. And make sure the added _val
is not enumerable so it does not appear. Hope that helps; good luck!