0

I'm working on a calculator in react js. When I add two numbers it gives me the right answer but after I click on the minus button it adds first Value to the result and gives me the addition result. I'm trying to figure out where the problem is but I can't. Here is the code of my operation function

import React, { Component } from 'react';



export default class Calculator extends Component {
constructor(props)
{
    super(props)
    {
            this.state={
                value:'0',
                firstValue:0,
                operation:'',
                previousvalue:'',
                nextvalue:'',
                showingTemporaryResult:false
            }
    };
    this.handleclick=this.handleclick.bind(this);
    this.operation=this.operation.bind(this);
    this.cleardisplay=this.cleardisplay.bind(this);
    this.dot=this.dot.bind(this);
    this.changesign=this.changesign.bind(this);
    this.percent=this.percent.bind(this);


}
handleclick(digit)
{    
    if(this.state.showingTemporaryResult) {
        console.log("TRUE CALLED");
        this.setState({value:String(digit),showingTemporaryResult:false})
    }
    else {
        console.log("ELSE CALLED");
        this.setState({value:this.state.value==='0'?String(digit):this.state.value + digit});
    }


   // console.log('helo click fire',this.state.value);

}
cleardisplay()
{
     this.setState({value:'0',
     firstValue:0,
     operation:'',
     previousvalue:'',
     nextvalue:'',
     showingTemporaryResult:false});
}
dot()
{
    if(this.state.value.indexOf('.')===-1)
    {
        this.setState({value:this.state.value+'.'})
    }
}
changesign()

{
    console.log("Event Change Sign")
    if(this.state.value.charAt(0)==='-')
    {
        this.setState({value:this.state.value.substr(1)})
       // console.log(' sign not change');

    }
    else{
        this.setState({value:'-'+this.state.value})
        console.log('lets change sign');
    }

}
operation(operator)
{


    if(operator==='+'||operator==='-'||operator==='*'||operator==='/')
    {
        console.log('operator coming',operator);
       this.setState({operation:operator});
       console.log('operator coming',this.state.operation);
        if(this.state.operator === '+') {
            let secondValue = parseInt(this.state.value);
            let firstValue = parseInt(this.state.firstValue);
            console.log('chcking first value in plus ',firstValue);
            let sum = secondValue+firstValue;
            this.setState({firstValue:sum,value:sum,showingTemporaryResult:true,operation:operator});
            //console.log('somthing here ');
        }
        else if(this.state.operator==='-')
        {
            let secondValue = parseInt(this.state.value);
            let firstValue = parseInt(this.state.firstValue);
            console.log('chcking first value in minus ',firstValue);
            let sum = secondValue-firstValue;
            this.setState({firstValue:sum,value:sum,showingTemporaryResult:true});
        }

        else if (this.state.operation === '') {
            let firstValue = parseInt(this.state.value);
            this.setState({firstValue});
            this.setState({value:'',operation:operator});
            console.log('or here ');
        }

    }
    else if(operator==='=')
    {
        if(this.state.operation === '+') {
            let answer = parseInt(this.state.value) + parseInt(this.state.firstValue);
            this.setState({value:answer});

        }
        else if(this.state.operation==='-'){
            let answer = parseInt(this.state.value) - parseInt(this.state.firstValue);
            this.setState({value:answer});
        }

    }



}
percent()
{
    this.setState({value:this.state.value/100})
}

render() {
return (
  <div className="cal">

      <input type="num" name="res" value={this.state.value} disabled style={{height:'8vh',width:'47vh',backgroundColor:'black',color:'white',fontSize:'20px'}}/><br></br>
      <input type="button" name="ac" onClick={() => this.cleardisplay()} value="Ac" style={{height:'5vh',width:'12vh',backgroundColor:'#ccced1',border:'1px solid black'}}/>
      <input type="button" name="+/-" onClick={() => this.changesign()} value="+/-" style={{height:'5vh',width:'12vh',backgroundColor:'#ccced1',border:'1px solid black'}}/>
      <input type="button" name="%" onClick={() => this.percent()}value="%" style={{height:'5vh',width:'12vh',backgroundColor:'#ccced1',border:'1px solid black'}}/>
      <input type="button" name="/" onClick={() => this.operation('/')} value='/' style={{height:'5vh',width:'12vh',backgroundColor:'#ff9100',border:'1px solid black'}}/>

      <br></br>
      <input type="button" name="7" onClick={() => this.handleclick(7)} value="7" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="8" onClick={() => this.handleclick(8)} value="8" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="9" onClick={() => this.handleclick(9)} value="9" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="*" onClick={() => this.operation('*')} value='*' style={{height:'5vh',width:'12vh',backgroundColor:'#ff9100',border:'1px solid black'}}/>

      <br></br>
      <input type="button" name="4"  onClick={() => this.handleclick(4)} value="4" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="5" onClick={() => this.handleclick(5)} value="5" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="6" onClick={() => this.handleclick(6)}value="6" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="-" onClick={() => this.operation('-')} value='-' style={{height:'5vh',width:'12vh',backgroundColor:'#ff9100',border:'1px solid black'}}/>

      <br></br>
      <input type="button" name="1" onClick={() => this.handleclick(1)} value="1" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="2" onClick={() => this.handleclick(2)} value="2" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="3" onClick={() => this.handleclick(3)} value="3" style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="+" onClick={() => this.operation('+')} value='+' style={{height:'5vh',width:'12vh',backgroundColor:'#ff9100',border:'1px solid black'}}/>

       <br></br>
      <input type="button" name="0" onClick={() => this.handleclick(0)} value="0" style={{height:'5vh',width:'24vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="." onClick={() => this.dot()} value="." style={{height:'5vh',width:'12vh',backgroundColor:'#d2d4d8',border:'1px solid black'}}/>
      <input type="button" name="=" onClick={() => this.operation('=')} value="=" style={{height:'5vh',width:'12vh',backgroundColor:'#ff9100',border:'1px solid black'}}/>



  </div>
    )
    }
     }

now i add my whole component in post .........................................................................................................................................................................................................................................

2 Answers 2

1

You are setting the state and then checking for it's value. You need to understand that setState is an asynchronous action and you cannot count on it's value being changed right after you call it.

Based on the react docs:

Calls to setState are asynchronous - don’t rely on this.state to reflect the new value immediately after calling setState. Pass an updater function instead of an object if you need compute values based on the current state (see below for details).

In your code you are changing the state: this.setState({operation:operator}); and then checking for it's new value if(this.state.operation === '+').
You should be checking the operator or make the actions after the state changes with componentDidUpdate or the callaback of setState
this.setState({operation: operator}, () => {if(this.state.operation === '+')})

Edit:
After your edit I see two problems:

  1. Your architecture isn't good, you saw that sometimes you receive an empty operator after setting it and had some patchy if statement, you can remove it once moving your code to the callback.

  2. When your setting your state, you should clear your value as it isnt relevant anymore. in this line:
    this.setState({firstValue:sum,value:sum,showingTemporaryResult:true,operation:operator});

Sign up to request clarification or add additional context in comments.

11 Comments

i did this change operator at the place of operation but what should i make chanings in the condtion else if (this.state.operation === '') { let firstValue = parseInt(this.state.value); this.setState({firstValue}); this.setState({value:'',operation:operator}); console.log('or here '); }
Couldn't understand your question now but the problem is that you are using the wrong operator because your still hasnt changed yet to the new operator.
can i mail you my code ??would you like to share ur email ?
No need. Just edit your post with the code and i'll respond again
@bilalahmad123456 Can you explain your problem? did you try to move the code to the callback of setState?
|
0

I tihnk you are ancounter some bugs because setState is not synchronous. If you want to execute something after state is set to new value you need to pass callback as a second parameter. Please take a look at this snippet of code:

constructor() {
  this.state = {
    foo1: 'bar',
    foo2: 'bar'
  }
}

someMethod() {
  this.setState({foo1: 'baz});
  console.log(this.state.foo1); // outputs "bar"
}

someDifferentMethod() {
  this.setState({foo2: 'baz}, () => {console.log(this.state.foo2)});
  // outputs "baz"
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.