Build a JavaScript Calculator, weird undefined onClick

Tell us what’s happening:
I really need some help with this, I’m just trying to make the numbers get added to the display when clicked, however, sometimes it just adds “undefined” to the display, but then you click the same element again and you do get the number. I have no clue, I hope you guys can help me out!

Your code so far
Index.js:

class App extends React.Component {
	constructor(props) 
		super(props);
		this.state = {
			text:"",
		}
		this.handleClick = this.handleClick.bind(this);
	}

	handleClick(event) {
		let cases = {
			'one':'1',
			'two':'2',
			'three':'3',
			'four':'4',
			'five':'5',
			'six':'6',
			'seven':'7',
			'eight':'8',
			'nine':'9',
			'zero':'0',
			'add':'+',
			'subtract':'-',
			'multiply':'*',
			'divide':'/',
			'decimal':'.',
		};
		let clickedKey = cases[event.target.id];
		this.setState({
			text:this.state.text + clickedKey,
		})
	}

	render() {
		return(
			<div id="calculator">
				<Display text={this.state.text} />
				<Keypad clickAction={this.handleClick} />
			</div>
		)
	}
}

Keypad.js:

const Keypad = props => {
	return (
		<div className="keys">
			<div className="row">
				<div className="key" id="clear"><h2>AC</h2></div>
				<div className="key" onClick={props.clickAction} id="add"><h2>+</h2></div>
			</div>
			<div className="row">
				<div className="key" onClick={props.clickAction} id="seven"><h2>7</h2></div>
				<div className="key" onClick={props.clickAction} id="eight"><h2>8</h2></div>
				<div className="key" onClick={props.clickAction} id="nine"><h2>9</h2></div>
				<div className="key" onClick={props.clickAction} id="subtract"><h2>-</h2></div>
			</div>
			<div className="row">
				<div className="key" onClick={props.clickAction} id="four"><h2>4</h2></div>
				<div className="key" onClick={props.clickAction} id="five"><h2>5</h2></div>
				<div className="key" onClick={props.clickAction} id="six"><h2>6</h2></div>
				<div className="key" onClick={props.clickAction} id="multiply"><h2>*</h2></div>
			</div>
			<div className="row">
				<div className="key" onClick={props.clickAction} id="one"><h2>1</h2></div>
				<div className="key" onClick={props.clickAction} id="two"><h2>2</h2></div>
				<div className="key" onClick={props.clickAction} id="three"><h2>3</h2></div>
				<div className="key" onClick={props.clickAction} id="divide"><h2>/</h2></div>
			</div>
			<div className="row">
				<div className="key" onClick={props.clickAction} id="zero"><h2>0</h2></div>
				<div className="key" onClick={props.clickAction} id="decimal"><h2>.</h2></div>
				<div className="key" id="equals"><h2>=</h2></div>
			</div>
		</div>
	)
}

Display.js:

const Display = props => 
		<input type="text" id="display" value={props.text} readOnly/>

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/75.0.3770.90 Chrome/75.0.3770.90 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/front-end-libraries-projects/build-a-javascript-calculator/

Well, for whatever reason, changing

<div className="key" onClick={props.clickAction} id="seven"><h2>7</h2></div>

To

<div className="key" onClick={props.clickAction} id="seven">7</div>

Fixes the issue, I wonder why that h2 would give issues though

I think what has happened here, is the click event is actually happening inside the H2,

which does not have an Id,

so it is passing e.target.id up to state, and it only happens sometimes because your clicking on the div and getting the id some times,

you can verify this by adding margin to the h2 element and retesting.

1 Like

why do you want to worst your time to open and close many html tag. just use map

state={
cases:[1,2,3,4,5,6,7,8,9,10,*,+,-,/]
}
onClickHandler=(id)=>{
let clickedButtonValue=this.state.cases[id]
//this id is the index(i) which we pass from map 
}
render(){
let someVariableName= (<div syle={{width:"400px"}}>
{this.state/case.map((item,i)=>{
return (<div style={{display:"inlineBlock"}} key={i} onClick={this.onClickHanler.bind(this,i)}>{item}</div>)
// here we pass the index (i) of item from case array which you can access in your
onClickHanler method
})}
</div>)
return(
{someVariableName}

)

}