Reputation: 1701
I am a newbie to nodejs. I am writing a helper function to build JSON using a schema, I am trying to add functions (mostly setters) to set values. The following is a simple version of it.
function Task() {
this.action = {};
this.schedule = {};
}
function capitalize(str) {
return `${str[0].toUpperCase()}${str.slice(1)}`;
}
const scheduleProps = [
'startAt',
'repeatEvery',
'endAt',
'count',
'interval'
];
Add methods to it dynamically
for(var i=0; i<scheduleProps.length; i++) {
Object.defineProperty(Task.prototype, `set${capitalize(scheduleProps[i])}`, {
enumerable: true,
configurable: false,
writable: true,
value: (value) => {
this.schedule[scheduleProps[i]] = value;
}
});
}
When I call the following way I expect obj.schedule.repeatEvery to contain value 10.
obj = new Task();
obj.setRepeatEvery(10);
Instead I get
TypeError: Cannot set property 'repeatEvery' of undefined
I even tried to set the functions like so
Task.prototype[`set${capitalize(scheduleProps[i])}`] = (val) => {
this.schedule[scheduleProps[i]] = val;
}
In this case I get
TypeError: Cannot set property 'interval' of undefined
at Task.(anonymous function) [as setRepeatEvery]
How can I set methods to a function.prototype dynamically? Thanks a lot for your help
Upvotes: 2
Views: 349
Reputation: 774
You were facing that issue mainly because of function assignment for "value" key.
You can find some changes there which is creating a closure and also changed the syntax of assigning a function at key of an object.
Closure is created to maintain the value of i for that particular iteration.
function Task() {
this.action = {};
this.schedule = {};
}
function capitalize(str) {
return `${str[0].toUpperCase()}${str.slice(1)}`;
}
const scheduleProps = [
'startAt',
'repeatEvery',
'endAt',
'count',
'interval'
];
for(var i=0; i<scheduleProps.length; i++) {
Object.defineProperty(Task.prototype, `set${capitalize(scheduleProps[i])}`, {
enumerable: true,
configurable: false,
writable: true,
value: (function(i) { return function(value) { this.schedule[scheduleProps[i]] = value;} })(i)
});
}
obj = new Task();
obj.setRepeatEvery(10);
Upvotes: 1