Reputation: 99
I'm new to javascript and I'm doing a little app in react as an exercise but I'm stuck on a weird problem. I'm trying to call a method inside another method of a same class and it doesn't always work.
export class Core {
constructor() {
this.promptList = ["Are you sure you want to proceed? [Y/n] ",
"Enter a username: ",
"Enter your email: "];
this.funcList = [this.proceed,
this.validateUser,
this.validateEmail];
this.currentStep = 0;
}
incStep(state) {
const newState = Object.assign({}, state,
{prompt: this.promptList[++this.currentStep]});
return newState;
}
printError(state, error) {
console.log("error");
return Object.assign({}, state,
{history: state.history.concat(error)});
}
proceed(input, state) {
if (input == "Y")
return this.incStep(state);
else if (input == "n")
return this.printError(state, "ok bye");
return state;
}
validateUser(input, state) {
return state;
}
validateEmail(input, state) {
return state;
}
process(input, currentState) {
const newState = Object.assign({}, currentState,
{history: currentState.history.concat(input)});
return this.funcList[this.currentStep](input, newState);
}
}
In process(), I call a method from the list of function and this works fine but when I try to call incStep() from proceed() an error is thrown
Uncaught TypeError: this.incStep is not a function
at Array.proceed (http://localhost:8080/index_bundle.js:31881:34)
at Core.process (http://localhost:8080/index_bundle.js:31898:42)
I'm guessing that the error is due to the fact that "this" does not refer to the good object but I don't understand exactly why in this case :/
What am I doing wrong here ?
Upvotes: 1
Views: 50
Reputation: 1079
your code is failing because of these parts.
this.funcList = [this.proceed,
this.validateUser,
this.validateEmail];
you need to remember array is speacial kind of object in js so it is equivalent to
this.functList = {0:refrence of proceed,
1:refrence of validateUser,
2:refrence of validateEmail,
length:3
}
When a function is called as a method of an object, it's this is set to the object the method is called on. So when
this.funcList[this.currentStep](input, newState);
was called and proceed was executed, this belonged to the objet it resides on, which in this case was the funcList array.
proceed(input, state) {
if (input == "Y")
return this.incStep(state);
hence this call inside proceed refers to the funclist array and not the class and fails.
Using bind to set this is one way to fix this.
this.funcList = [this.proceed.bind(this),
this.validateUser.bind(this),
this.validateEmail.bind(this)];
Upvotes: 2