Need help with vanillaJS Calculator Project

Guys, I’m almost through with my JS calc but for one minor problem. It’s with user story #13 which states:

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

The sequence “5 * - 5” = should produce an output of “-25” : expected ‘0’ to equal ‘-25’ AssertionError: The sequence “5 * - 5” = should produce an output of “-25” : expected ‘0’ to equal ‘-25’

(excluding the negative (-) sign was not listed as a criterion in the project page until I ran the tests. Been trying out various things on my handle operator function but nothing seems to work. kindly check and give tips/help if possible.

https://codepen.io/supercede/pen/EqNzjq

Arigato

I’m trying to understand your code. Could you loosely explain how it works? What is the purpose of operatorFlag?

It checks for if an operator has been pressed

And (, pardon me, ) I am unfamiliar with this syntax:

let { firstOperand, operator, displayValue, operatorFlag } = calculator;

Does it mean to set all those variables equal to the calculator object? Or is it saying to set them equal to the calculator object’s properties of the same name?

Also, when you use operator as a condition, that’s just checking if it is set, right? Or is operator supposed to be a boolean?

That line is using what’s known as ‘Object Destructuring’ - if you haven’t gotten to that lesson in the JS course yet, you will. :wink:

Basically, it’s taking the calculator object, which contains properties with the names calculator.firstOperand, calculator.operator, calculator.displayValue and calculator.operatorFlag, among others, and is assigning them to variables of those same names: calculator.firstOperand becomes firstOperand, for example. Easy way to use the object to create independent variables of the same name.

Note that this isn’t a reference back to the original object - firstOperand is a pure variable in its own right, and not a pointer to the calculator.firstOperand. This is important, because it helps to preserve the immutability of data. :wink:

Thanks, sir, I just learned something very important.

1 Like

Not that operator is a boolean, but that it exists. If the property was null on the object, then the variable would be null as well, which could be considered a ‘falsy’ value.

What that conditional is saying is, “If there is an operator, and the operator flag has already been set to true… do this.”

Which could be a place to consider: you may want to add properties for ‘firstOperatorSign’ and ‘secondOperatorSign’ - if the current display is 0, or if an operator has been pressed, and the minus is then pressed, set the appropriate operatorSign.

Object destructuring is a very very powerful tool. It can help streamline a LOT of code, among other useful reasons for it.

Good questions!

Ah, I understand now! It just uses the last operator entered! *facepalm*

I agree, but I want to see if we can solve it using one operator. In the case of the user entering a negative after the first operator is already set, the secondOperand should just be a negative number…

Right, but what if the display is cleared currently, and the user tries to enter ``- 5 * 3? The displayed value is0`, and a negative zero… Hmmm…

Actually, I misspoke - you don’t want a firstOperatorSign/secondOperatorSign - you would need a firstValueSign and secondValueSign. If an operator has been entered (only one), and a second operator is entered, if it’s a -, then the appropriate valueSign flag should be set. Otherwise, the existing operator is simply replaced.

In each case, the value for that sign hasn’t yet been created - when the - is hit, the value for it hasn’t been entered. So you’ll need somewhere to keep that minus, until a value has been entered. Once there’s a value, you can check if it’s got a minus valueSign flag, and at the first step, multiply it by -1. then clear the valueSign flag. :wink:

No, if you put -5 * 3 and press the = sign, calculator.displayValue = -15.

I’m thinking of the following edit around line 38:

if (operator && operatorFlag === true)
 {
    if(/*the newOperator is -*/)
    {
        //some boolean indicating that secondOperand < 0 is set to true
    }
    else
    {
        calculator.operator = newOperator;
        return;
    }
 }

Then, where line 45 is (before the edit), you put:

calculator.secondOperand = parseFloat(displayValue);

if(/*that special boolean is true*/)
{
    calculator.secondOperand *= -1; //set it to negative
}
const result = calculate[calculator.operator](
      calculator.firstOperand,
      calculator.secondOperand
    ); //and so on...

I just don’t yet know how to check if the value of newOperator is -

1 Like

Wow. Know why the ‘first’ number is working as you expect? because it’s doing 0 - 5 * 3 - it’s not treating that initial minus as a negative, it’s treating it as an operator, and subtracting from zero. Nice.

and why not simply

if(newOperator === '-'){
  // Yup, the user entered a minus...
}

Let us know if that answers your question

Thanks for sharing,excelent work

Still can’t make it work. Can you help me make an edit please?

Alright, sir, I have solved the problem. First you edit the handleOperator function as I said above:

if (operator && operatorFlag === true)
 {
    if(newOperator === '-')
    {
        //boolean indicating secondOperand < 0 set to true;
    }
    else
    {
        calculator.operator = newOperator;
    }
    return;

However, the second edit should be in the inputDigits function:

if (calculator.operatorFlag === true) {
    if(/*the boolean is true*/)
    {
        digits *= -1;
    }
    calculator.displayValue = digits;
    calculator.operatorFlag = false;
    //the boolean = false;
  }

Hey man, It worked! Thanks. Haven’t edited it on codepen yet though, will do soon

1 Like