Skip to content
Advertisement

Need help for a Vue – BMI Calculator

I am learning Webdev with Vue. And in my project, I built a component to calculate the BMI of a person. I have created a form with bootstrap-vue to get the values I need. And now I need help for the JavaScript part. I just don’t know how to correct it.

<template>
  <div class="bmi-calc">

      <b-card title="BMI Calculator" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article" style="max-width: 20rem;" class="mb-2">

        <b-form @submit="onSubmit" v-if="show">
            <!-- Height -->
            <b-form-group id="input-group-height" label="height" label-for="input-height" description="Height in cm">
                <b-form-input id="input-height" v-model="form.height" type="height"></b-form-input>
            </b-form-group>
            <!-- Weight -->
            <b-form-group id="input-group-weight" label="weight" label-for="input-weight" description="Weight in kg">
                <b-form-input id="input-weight" v-model="form.weight" type="weight"></b-form-input>
            </b-form-group>
        </b-form>

        <b-button type="submit" variant="primary">Submit</b-button>
        <div>Solution is: <strong>{{ solution }}</strong></div>

        </b-card>
    </div>
</template>


<script>
export default {
  data () {
    return {
      form: {
        height: '',
        weight: ''
      },
      show: true
    }
  },
  methods: {
    onSubmit (evt) {
      evt.preventDefault()
      var solution = null
      solution = this.weight / (this.height) ^ 2
    },
    onReset (evt) {
      evt.preventDefault()
      // Reset our form values
      this.form.height = ''
      this.form.weight = ''
      // Trick to reset/clear native browser form validation state
      this.show = false
      this.$nextTick(() => {
        this.show = true
      })
    },
  }
}

</script> 

Formula I have used: 1

Answer

A few issues:

  1. The Submit-button should be inside the form in order to trigger asubmit-event properly:
<b-form>
  <b-form-group>...</b-form-group>

  <b-button type="submit">Submit</b-button>
</b-form>
  1. The template refers to solution, but that’s only a local variable inside onSubmit(). To make that available for rendering, initialize it as a prop from data(), as shown below. You’ll later set it in onSubmit() by using this.solution = /* new value */.
export default {
  data() {
    return {
      //...
      solution: 0,
    }
  }
}
  1. onSubmit() refers to this.weight and this.height, but those values are actually stored under this.form, so they should be this.form.weight and this.form.height, respectively.

  2. The BMI calculation is not using the correct syntax to square a number. You could either use Math.pow(), or just multiply it with itself:

export default {
  methods: {
    onSubmit() {
      this.solution = this.form.weight / Math.pow(this.form.height, 2)
      // OR
      this.solution = this.form.weight / (this.form.height * this.form.height)
    }
  }
}
  1. The <b-form-input>s are bound to form.height and form.weight, but those are currently strings, which will result in an error in the BMI calculation, which requires numbers. Currently, the input types are incorrectly set to type="height" and type="weight", but those should be type="number". Also, when using v-model for a number, make sure to use the .number modifier so that the value is updated to the correct type:
<b-form-input v-model.number="form.weight" type="number">
<b-form-input v-model.number="form.height" type="number">

Edit Binding to number inputs

Advertisement