I ran the tests on my javascript calculator and they are failing even though i get the proper result when inputting them into the calculator. Im not sure how the tests work maybe because i have two ids of display with diff variables it messes them up.
for test 9. 5-9+5 = 1 if i type this into the calculator and hit equals i get 1
12. 5*5.5= 27.5 also get the right answer when i type this in
same for tests 13 and 14 i get the correct results when i type them directly into the calculator so i am unsure why these would fail.
Alright i’ve changed the code to just have one element with an id of display and it didn’t change any of the test results. I have tried putting the id on the outer div to cover both variables and on each of the divs that contain the output state but the tests still dont pass. The calculators output seems perfect except that the zero doesn’t initially disappear after the calculator is reset.
Yeah i know that i also figured out what the prob was with the other tests my calculator wasn’t clearing the result after equals was pressed and if a number was typed it just added that number to the previous result. So now all the tests pass except for the display not showing zero which i already knew wasnt right
I guess it is not designed to look at two different variables at once if I name the div surrounding the two variables display only 9 tests pass for some and the reset test passes. If name the div for my calculations display 15 tests pass but the reset test fails. I give up for tonight ill work on this again tommorrow.
I was able to have the variable initialize with zero upon hitting the reset but now fewer tests are passing. I am pretty sure they are failing because i am getting an error (SyntaxError: expected expression, got ‘*’) but i have no idea what is causing this error. Has anyone seen this error before?
You are getting this error because of the way you are attempting to update state based on previous values of state in all of the if statements in the ButtonNum function. setState is asynchronous. You can not be guaranteed the value of current state until the render unless you are using the functional version of setState (which you learned about in the curriculum). This means you can write:
React does not immediately update state. It does so in batches and only guarantees the value of state within the render method. Honestly, it would be best to only have a single this.setState at the end of the if statements where you would update all the necessary state properties.
When the tests run, the buttons are clicked very fast, so because of the way your are checking state and updating state based on a previous value of state, your calculator ends up using eval on strings that are not what is actually typed leading to one of the tests that is testing 5 x 5.5 = but your eval statement ends up looking like eval(*5.5) instead of eval(5*5.5), which is why you get the SyntaxError: expected expression, got '*' error. eval can not evaluate that expression as it is not proper syntax to evaluate. This is a really good reason NOT to use eval in general. It hides issues like this until runtime.
Extra Notes:
I notice you have ref="button1". What is the purpose of this?
Your character set regular expressions and if statement conditions are overly complex in general. Instead of writing:
if (/[-]|[+]|[*]|[/]|[=]/.test(event.target.value) === true) {
you could just write:
if (/[-+*/=]/.test(event.target.value)) {
Some of your state property names are not very descriptive (i.e id, num1, id2) and makes it very difficult to quickly read your code and try to assess what you are trying to do. State property names should be like variable and function names. They should be describe the data contained by them.
Ok it makes sense I’m going to see if I can get it working without updating all the code. That explains why my console.logs where off when i was trying to troubleshoot the code.
You will need to update a lot of code. I was able to get your app working with most of the logic but it had to be rearranged, refactored, and some parts completely deleted to get it to work.
Im still not completely understanding how to make sure i am using the current state i understand that the states are updated in batched so i changed my state set states to the functional version but still it hasn’t changed my results not passing. I have tried using componentDidUpdate at one point but i get errors.
Also is there a good way to troubleshoot code using console log when working with react it always seems one state behind maybe that is the problem with my code tho. I was just using the output screen when i wrote the code so it seemed to work perfectly.
You are still using this.state in the functional version. Use state instead. I am not saying this will allow you to pass the tests as there is some logic issues still, but it could definitely help.
Also, I do not understand why you are using the id state property that never gets rendered (see code below). If it is not rendered, you do not really need it to be tracked in state. It can just be a variable.
if (/[0-9]/.test(event.target.value) == true) {
let x = event.target.value
this.setState(state =>({
id: [...this.state.id, x]
}));
}
if (/./.test(event.target.value) == true && this.state.id.indexOf('.') == -1) {
let x = event.target.value
this.setState(state =>({
id: [...this.state.id, x]
}));
}
Also, you still have made no changes to your regex. You are using regex where it is not even needed. See below for an example:
/[.]/.test(event.target.value) == true
The above condition could simply be written as event.target.value == '.'
Lastly, I see the following code repeated throughout your if statements. Why? You only need to make that assignment one time at the beginning of the function as the value of event.target.value will not change within a call to the function.
I put a console log in the function when equals is hit and it shows the correct input and i get the correct output on the calculator so im confused as to why its is still failing. Also i do use this.state.id to keep track of decimals so they cant be repeated. Also yeah i still know some of the regex is unnecessary but i works ok.
But like I told you before, you can only be guaranteed the value of the state property id within the functional version of setState or the render function. Accessing a state property outside of those two places may not always have the current value due to the asynchronous nature of how state is updated by React.
You need to move all references to state properties to one of those two places. Also, like I told you before, you will have to rewrite a lot of your code to get this to work properly.
I changed the code so everything in my equals function is within the functional setstate. so now everything in my code is in functional setstates but still doesnt work. Is there a way i can tell using console logs if it is working correctly. Ive only been programming for two months now so im still pretty much a beginner at this. I really appreciate your help though.
That is what I recommended early on. You can then have a single this.setState to only update the main display property (num1) and the secondardy display property (id2). You will then not need the id state property.