Javascript Calculator Project -- SOO HARD! XD

UPDATE: Currently at 15/16

Couldn’t quite figure out this:

If 2 or more operators are entered consecutively, the operation performed should be the last operator entered (excluding the negative (-) sign.

UPDATE: Currently at 14/16

WIP React Calculator Project.

I’ve restarted probly 5 times. 2 of which, I followed tutorials on Youtube. Although I liked their code better because it looked much cleaner, their finished projects don’t really solve the user stories to pass the FCC project. 3 times I restarted, because I was just stuck, with too many line of code ( 300+). Changing one line will solve one problem but introduce another.

Almost on my 4th week on this, I’m hoping this is my last attempt and will finally pass all challenges. Because now, I am asking for help. It just felt that I could do it, those last 5 times. But now, I accept defeat, well not really… I accept that I need help. :smiley: Maybe every developer does, or did at some point right? :smiley:

So here’s the current code:

export default class Calculator extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      previousOperand: "0",
      currentOperand: "0",
      isOperational: false,
      isPositive: true,
      isDefault: true
    };
  }

  
  handleClear = () => {
    this.setState({
      previousOperand: "0",
      currentOperand: "0",
      isOperational: false,
      isPositive: true,
      isDefault: true
    });
  };


  handleDel = () => {
    this.setState({
      currentOperand: this.state.currentOperand.slice(
        0,
        this.state.currentOperand.length - 1
      )
    });
  };

  
  handleEquals = () => {
    if (this.state.isOperational === false) return;

    this.setState({
      previousOperand: math.evaluate(this.state.previousOperand),
      currentOperand: "0",
      isPositive: true
    });
  };

 

  handleDecimal = e => {
    if (this.state.currentOperand.includes(".")) return;
    this.setState({
      currentOperand: this.state.currentOperand + e.target.value,
      previousOperand: this.state.currentOperand + e.target.value
    });
  };

  
  handleNumbers = e => {
    const value = e.target.value;

    switch (value) {
      case "0":
        this.handleZero(value);
        break;
      default:
        this.handleInput(value);
        break;
    }
  };

  handleOperations = e => {
   
    if (
      (this.state.previousOperand === "" &&
        this.state.currentOperand === "0") ||
      this.state.currentOperand === "0."
    ) {
      console.log(`returning because this is empty`);
      return;
    }

   
    else if (
      (this.state.previousOperand === "" &&
        this.state.currentOperand !== "0") ||
      (this.state.previousOperand === "" && this.state.currentOperand !== ".")
    ) {
      this.setState({
        previousOperand: this.state.currentOperand + e.target.value,
        currentOperand: "0",
        isPositive: true,
        isOperational: true
      });
    }

  
    /* IS THIS BREAKING MY APP????
    else if (this.state.currentOperand.endsWith(".")) {
      const replaced = this.state.currentOperand.replace(".", "");
      this.setState({
        previousOperand: replaced + e.target.value,
        currentOperand: "0",
        isPositive: true,
        isOperational: true
      });
    }
    */

  
    else {
      this.setState({
        previousOperand: this.state.previousOperand + e.target.value,
        currentOperand: 0,
        isPositive: true,
        isOperational: true
      });
    }
  };

  handleZero = input => {
    //handlezero
    if (input === "0") {
      if (this.state.currentOperand === "0") {
        return;
      } else {
        this.handleInput(input);
      }
    }
  };

  handleInput = input => {
    if (
      this.state.currentOperand === "0" &&
      this.state.previousOperand === "0"
    ) {
      this.setState({
        currentOperand: input,
        previousOperand: input,
        isDefault: false
      });
    } else {
      this.setState({
        currentOperand: this.state.currentOperand + input,
        previousOperand: this.state.previousOperand + input
      });
    }
  };

  render() {
    return (
      <div className="calc-wrapper">
        <Display
          isDefault={this.state.isDefault}
          previousOperand={this.state.previousOperand}
          currentOperand={this.state.currentOperand}
        />
        <Buttons
          handleNumbers={this.handleNumbers}
          handleClear={this.handleClear}
          handleEquals={this.handleEquals}
          handleDel={this.handleDel}
          handleDecimal={this.handleDecimal}
          handleOperations={this.handleOperations}
        />
      </div>
    );
  }
}

So some of my thoughts at the moment:

  1. I included a (±) button to handle negative values, and a state of isPositive, but i realized it might still not pass the challenge, because it wants the actual “subtraction” key to do that. So I might actually omit that part.

  2. I’m using mathjs btw, all the other times I didn’t, I think this just helps lessen my code by a few lines. Although manual coding +, -, *, /, weren’t really hard. I just wanted to give this a try and seems to work nicely (when it was workin – before I added more lines of code – lol).

  3. Do I need a polyfill for endsWith()? because it’s breaking the app. If I keep that part of else if it breaks, and commenting it out, I don’t get any error. I don’t even know how to add polyfill. Haha! :smiley:

I’ll try to look at what you are running into with your code, but I can to ask right away if you are using console.log messages and looking at your console results to see what your code is doing. If you are not you need to learn to do this as coding problems become more complex. Codepen.io makes this very convenient as they provide code, result and console all on one screen.

1 Like

I do console.log() quite a lot actually… I try not to include them on my post along with my //comments so as to clean my post up a bit…

Last problem I have to solve now , is the consecutive operators part. So 5 * / - + 5 should equal 10. My calculator evaluates this string to 25. I think I need RegExp to solve this, and I’m really very bad at it at the moment.

Is there any way I can see the current state of your code? That would be the other thing about using Codepen. Others can see and get at your code to help you and your code is up to date. I don’t know if hosting on netify has any options to share your code with others.

hmm, i think i should use github instead. I’m not using codepen to practice working locally anyways and I do need to learn to use github too. Will that work for you though?

It would provide access to the code and I believe that the project could be pulled into codepen from there.

ok, i got it to post on Github. React Calculator. Dunno how to pull it from Codepen though. Let me see if I can figure that out.

Well you go to codepen.io and make an account then you click create a new pen. Then save it up and post it here :3

I do have a codepen account. But are you suggesting to copy my code manually to codepen?

It doesn’t look like there is an import in Codepen. (Rumor has it that that comes in a paid account.) I suggest you don’t spin your wheels looking for that.

You might be able to reference your Github repository as an “External Resource” (https://blog.codepen.io/documentation/editor/adding-external-resources/) but for a small project, copy and pasting the files is probably more straight forward.

Side note: exporting from Codepen to Github is reasonably easy and well documented.

1 Like

FYI: I’m going offline. It will probably be tomorrow morning before I can look at this more.

1 Like

All good! Thanks for trying! :smiley: Good night…

now u get it :3 yep yup

thanks that was very helpful :smiley:

Hey! Didn’t want you to think I forgot you. I’ve been thinking about the calculator problem and what your code needs to do still. Before resorting to RegExp, I suggest you think of processing the sequence of button clicks, character by character.

You are collecting three things, the first operand (number) the operator (+, -, x, /) and the second operand (number).

If you work your why through the characters left to right, you should throw away any characters that are not a number character, these include (0-9, “.” and “-”) once a operator key is pressed, you have completed collection of the first operand and you have the operator.

Note: the “-” key is a little funny because it can be either part of a negative number or the operator for the calculation.

The next key will either be another operator, and therefore replaces the operator you previously had, or a number character is pressed and you’ve begun to collect the second operand. Collecting the second operand continues until either another operator or the “=” sign is pressed.

The the calculation is performed and the result is designed the first operand for the next operator pressed or in case an operator is pressed after the equal sign to perform further math on the result.

Hopefully this helps a bit.

2 Likes

it does help! thanks!!! :smiley:

Let me know if you setup your project in codepen. I’ll look at it there, if you do.

Thank you! But i’m moving on to the Pomodoro Clock project now. I ‘sort of’ solved the problem with the calculator, but it still has many bugs. I plan to go back to all my projects and make them better eventually when I finish all the FCC Challenges.