lukeet
lukeet

Reputation: 491

adding event listener to to my page is causing issues

I'm making a nodejs app using react for some reason when I run yarn start I get this error "TypeError: btn_bmi.addEventListener is not a function". Anyone have any ideas why this would be setting it up like this has worked for me in the past I'm unsure what is causing the error?

import React from 'react';


var btn_bmi = document.getElementsByClassName('bmi_button');
     btn_bmi.addEventListener('click', calculate_bmi());

    function calculate_bmi() {
        let Weight = document.getElementsByClassName('bmi_weight').value;
        let Height = document.getElementsByClassName('bmi_height').value;
        let Age = document.getElementsByClassName('bmi_age').value;
        let Test = document.getElementsByClassName('test_print');
        let bmi_calc = Weight / Height / Height * 10000;
        let bmr_calc = 88.2 + (13.362 + Weight) + (4.799 + Height) - (5.677 + Age);

        //if nothing entered show error
        if (Weight, Height, Age == 0){
            alert("Please enter your Height, Weight and Age so we can achieve your goals!")
            }
            else{
            //
            Test.innerHTML = document.write= bmi_calc + bmr_calc;
            }

    }

function setup_page () {
    return (
    <div className='setup_main'>
     <input className= 'bmi_weight' type='number' placeholder='Weight in kg:'></input>
     <input className= 'bmi_height' type='number' placeholder='Height in cm:'></input>
     <input className= 'bmi_age' type='number' placeholder='Age:'></input>
     <button className='bmi_button'>calculate</button>
     <p className='test_print'></p>
     </div>
    );
    }

export default setup_page;

Upvotes: 1

Views: 162

Answers (3)

andrew oxenburgh
andrew oxenburgh

Reputation: 136

Also if (Weight, Height, Age == 0){ probably doesn't do what you think it does.

Upvotes: 0

TZiebura
TZiebura

Reputation: 514

React creates virtual DOM which cannot be accessed by document.querySelector and other similar functions. If you wish to access something created by react you must use this if you are using class component or hook useRef() if you are using function components(the name can be something else but I mean those: const MyComponent = props => ( <some-element />)). For your purpose you should create a form which holds its values in a state (either this.state or useState() hook)
EDIT
Below answer is quite right too but if you are using React to render your html the result of document.getElementsByClassname will return empty collection

Upvotes: 0

Jacob
Jacob

Reputation: 78850

document.getElementsByClassName(...) returns an HTMLCollection, not a single HTML element. That's because you can have multiple elements with the same class name.

If you want to assume only one comes back, replace with:

var btn_bmi = document.getElementsByClassName('bmi_button')[0];

Or, IMO the cleaner:

const btn_bmi = document.querySelector('.bmi_button');

But really, the best thing for you to do is to place the event listener in the JSX; that way, the event attachment/detachment is taken care of for you when React outputs the DOM and re-renders:

<button className='bmi_button' onClick={calculate_bmi}>calculate</button>

Upvotes: 4

Related Questions