Javascript Calculator keyPress and onClick is not updating same for the same method?

Hi, I am building the JavaScript calculator, and I binded keyboard keys NUMPAD but now the onClick method is not updating the result as like the keyPress method.

But I am using the same function (updateFormula) for handleKeyPress and handleClick Method so they should update the variables same (result, display and formula).

I tried many things but no luck yet.


The problem here is they are referring the same function which is this.updateFormula but giving me different results of showing output, onKeypress giving the value resulted array right away other is showing one lesser character but they use the same function.
I will be glad. Thanks in advance :slight_smile:

I think part of the problem involves:

else if(e.target.getAttribute("value") == arr[i][0]){

Since you are iterating through both numbers and numpad in your forEach, this will evaluate to true two times for each number clicked. Why? Let’s say you click the number 1 on the calculator, that means that when the 1 is evaluated from the numbers array, e.target.getAttribute("value") is equal to "1" and arr[i][0] is 1. You have used the == operator here, so it will evaluate to true. When the number 1 from the numpad array is checked, the same thing happens again, so the if statement gets evaluated as true.

This does not happen when a user pressed one of the items on the keyboard, because you are checking the keyCode property which have only one value for each key.

One more thing, I would suggest getting rid of the ternary operator here as you are trying to use it as a complicated if else. That is not the purpose of the operator and makes reading your code logic much more difficult than necessary.

1 Like

Thank you I will be following your ternary conditions advice. :slight_smile:

About the problem at the first my code was like this;


Here you can see that they are updating, with keyboard really at the same time, also the result section the formula is updating. Here is a result of updating result:
image

But using the onClick method is not updating this after another click which makes it updating later, Here is a pic of the onClick method is used:
image

I was able to make a few modifications to your code to get it to work correctly. I was correct about the array of duplicate numbers (from the numbers array and the numpad) array causing issues. You will need to make sure the array you use with the forEach does not include the duplicate numbers as elements (including the decimal characters).

You had also added an extra this.updateFormula(arr[i][0]); which I assume you had to do to get the display to update as you expected.

OK, so the real culprit in your code is how you are using setState at various places in your code. It is getting called at many places. In case you are not aware setState is asynchronous and React"batches" groups of calls to setState on its own. This means that sometimes when you try to reference this.state.someProperty at various points in various methods, it may not be updated as you think it should be. The render method will always have the latest state changes so it displays properly.

This FCC challenge on setState kind of glosses over how to handle this issue with a link to the React documentation. Basically, you need to pass a function to setState and the first argument of that function will contain the most current version of state for your app. Inside this function you would refer to whatever you want to name the function parameter (most people will name it state or prevState) and then replace all your references to this.state with state/preState. Also, you will need to return an object containing any of the updates to state properties you want to make.

An example of such a change would be in your updateFormula method:
Change the following:

this.setState({ formula: this.state.formula.concat(msg) });

to

this.setState(prevState => {
  return {
    formula: prevState.formula.concat(msg)
  };
});

Another problem you will run into is inside your solver method you reference this.state.formula, so you will need to see if you can figure out how to pass the current state to that method without referencing this.state.

See if you can make all the changes and if you get stuck, let us know and we can try to guide you a bit more to a workable solution.

1 Like

Here is another reference article for the functional use of setState.

1 Like

Thank you for your help and your interest :slight_smile:.

I went to React Documentation and understood the problem tried some solutions didn’t worked also Functional setState link or method either. I will be trying to use Redux for this project because I see that methods going to make this project more complicated than it should be :slight_smile:

I tried the setState((state)=>{formula: state.prevFormula})
(I defined also in “this.state” too)
which that was not working, also setState((prevState)=>{formula: prevState.Formula}) didn’t solved the problem.

I guess I m not that pro coder to handle those operations asyncronously with React. Seems like its better to dispatch actions aganist React, I was thinking that Redux could complicate things :slight_smile: Seems like its better to handle state changes with a store.

Redux is no game either, I need to change many things, dispatching actions in older react versions is a like a puzzle, I can use some help :sweat_smile: .
I am ready for that a bit more workable solution. Thank you for all your help Randell :slight_smile:.
Much appreciated.