JS calculator challenge help

I finally think i have all the operations but when i run tests, i still fail for some.

Im not sure why i fail for the display tests and i think that is triggering the other ones to fail

Any input is appreciated. If i know myself, i probably found a way to do this the complete opposite way it was designed.

When I try to run your app, it does nothing and I see this in the browser console:

react-dom.production.min.js:217 Uncaught TypeError: Cannot read properties of undefined (reading ‘__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED’)
at react-dom.production.min.js:217:172
at react-dom.production.min.js:13:195
at react-dom.production.min.js:13:223
at react-dom.production.min.js:267:3

pen.js:225 Uncaught TypeError: ReactDOM.render is not a function
at pen.js:144:10

I also see that you are manipulating the DOM in your code. That is a big, big, BIG no-no in React and can lead to unpredictable results.

1 Like

It seems to be something wrong with your React import. I removed your imports and redid them and it works.

do the tests pass when it worked for you?

do you think it has to do with me using the document.getElementById method?

No.

The first failing test is this:

7. At any time, pressing the clear button clears the input and output values, and returns the calculator to its initialized state; 0 should be shown in the element with the id of "display"

When I look, it appears to do it, but I have to ask:

<input type='text' class='col-12' id='display' placeholder={this.state.answer} />

Why is that an input? Do you want people to directly input to the display?

In any case, looking at the repo I see that this is the test:

      it(`At any time, pressing the clear button clears the input
      and output values, and returns the calculator to its initialized state; 0
      should be shown in the element with the id of "display"`, function () {
        clickButtonsById([_5, _x, _1, _plus, _5, _plus, _9, _2, _eq, _AC]);
        assert.strictEqual(
          getInputValue(document.getElementById('display')),
          '0',
          'Element with with id="display" should show 0 '
        );
      });

According to the error message after those operations, it is expecting ‘0’ there and it is getting an empty string. I don’t get that, but I do get an empty string when the app first starts up. I also notice that sometimes that value is a number and sometimes it is a string (usually not a good practice - though doesn’t seem to be the problem here).

But ultimately I don’t want to dig too deeply into this until you stop manipulating the DOM. I don’t know what is what - what React is seeing, what the virtual DOM is, what the actual DOM is, what the test are seeing…

thank you for the help. I think you can tell i have no clue what i am doing but i actually feel like i am taking small steps forward.

i appreciate all the diagnostics and will start with removing the DOM changing

1 Like

i got rid of the dom changes and changed the input to a p.

now going to deal with the last 2 challenges(the ones previously handles from the dom method)

1 Like

Trust me, I was where you are once - most of us were. Now I do React for a living. React is weird at first and is a different way of thinking. It’s really cool once you get it, but it’s weird for a while.

im definetly still at the weird stage. again, appreciate the help

Hey Kevin

I passed all the tests but i still am using the DOM manipulation :pleading_face: :pleading_face:

ill keep trying this for the rest of the day but then im going ot move on as i really want to finish this course.

Is it more important to finish the course or learn the material?

It’s late now but I’ll take a look toorrow.

truth.

ill dive back in tomorrow

So, each of these:

document.getElementById('decimal').disabled = false;

Instead of manipulating the DOM directly, let React do it. For example, you should set a flag in state like “shouldDisableDecimal”. And then in your JSX:

          <button
            className='col-3 pad'
            id='decimal'
            onClick={handleDec}
            value='.'
            disabled={this.state.shouldDisableDecimal}
          >
           .
          </button>

So, everywhere you manipulate that, you just change that state variable and it will be reflected in the JSX. That is a more React-y way to handle it. It should be a very easy change.

In general, I would also suggest thinking about how you structure your app. You have everything in one big component. You should be breaking them out into sub components. When starting out, just think of it visually. I would have thought about something like:

App
  Display
  Controls
    ButtonRow
      Button
      Button
    ButtonRow
      Button
      Button
      Button
      Button
    ButtonRow 
      Button
      // ...

And I would have created an array with the data I needed to pass into the controls. It would have been an array or row data, and each of the row arrays would be an object with the specific data that each button makes. This would have removed some duplication, broken your app into smaller pieces and separated out the logic from boring static data, making it easier to find things. Sure, it may seem unnecessarily complex for an app like this, but this is how you learn how to do that and this will be unbelievably important on any large app. I’m not saying to redo this one, but maybe do another little side project to get the idea.