TypeError: e is undefined in vue.js

Total
4
Shares

Now I’m getting frustrated 🙁 This is my very first attempt at using vue.js which after jQuery, is the second JS framework I’m learning since I came to this planet. I have the following HTML:

_x000D_

_x000D_

var main = new Vue({_x000D_
  el: ".main-content",_x000D_
  data: {_x000D_
    heading: "First Vue Page",_x000D_
    usdamount: 0,_x000D_
    currencies: [{_x000D_
        label: "GBP",_x000D_
        rate: 0.7214,_x000D_
        value: 0_x000D_
      },_x000D_
      {_x000D_
        label: "EUR",_x000D_
        rate: 0.80829,_x000D_
        value: 0_x000D_
      },_x000D_
      {_x000D_
        label: "CAD",_x000D_
        rate: 1.2948,_x000D_
        value: 0_x000D_
      }_x000D_
    ]_x000D_
  },_x000D_
  computed: {_x000D_
    updateCurrencies: function() {_x000D_
      console.log(this.usdamount);_x000D_
      var usd = parseFloat(this.usdamount);_x000D_
      for (var i = this.currencies.length - 1; i >= 0; i--) {_x000D_
        this.currencies[i].value = this.currencies[i].rate * usd;_x000D_
      }_x000D_
    }_x000D_
  }_x000D_
});

_x000D_

<script src="https://cdn.jsdelivr.net/npm/vue"></script>_x000D_
<section class="main-content">_x000D_
  <h1>{{ heading }}</h1>_x000D_
  <input type="number" v-on:change="updateCurrencies" v-model="usdamount">_x000D_
  <p class="cur-value" v-for="cur in currencies">_x000D_
    <strong>{{ cur.label }}</strong>: {{ cur.value }}_x000D_
  </p>_x000D_
</section>

_x000D_

_x000D_

_x000D_

When I load the page everything works fine and I get a zero logged on the console. If I try to change the input I get:

TypeError: e is undefined
Stack trace:
[email protected]://cdn.jsdelivr.net/npm/vue:6:26571
[email protected]://cdn.jsdelivr.net/npm/vue:6:7441
...

I went to the part that is complaining and got even more lost. It’s this function:

function we(t,e,n,r){(r||si).removeEventListener(t,e._withTask||e,n)}

I have no idea what’s causing the error even after several attempts to change things and isolate the problem.


Solution

computed is for automatic recalculation whenever an involved data property from your VM changes. To attach a method to an event handler, use methods block:

_x000D_

_x000D_

var main = new Vue({_x000D_
  el: ".main-content",_x000D_
  data: {_x000D_
    heading: "First Vue Page",_x000D_
    usdamount: 0,_x000D_
    currencies: [{_x000D_
        label: "GBP",_x000D_
        rate: 0.7214,_x000D_
        value: 0_x000D_
      },_x000D_
      {_x000D_
        label: "EUR",_x000D_
        rate: 0.80829,_x000D_
        value: 0_x000D_
      },_x000D_
      {_x000D_
        label: "CAD",_x000D_
        rate: 1.2948,_x000D_
        value: 0_x000D_
      }_x000D_
    ]_x000D_
  },_x000D_
  methods: {_x000D_
    updateCurrencies: function() {_x000D_
      console.log(this.usdamount);_x000D_
      var usd = parseFloat(this.usdamount);_x000D_
      for (var i = this.currencies.length - 1; i >= 0; i--) {_x000D_
        this.currencies[i].value = this.currencies[i].rate * usd;_x000D_
      }_x000D_
    }_x000D_
  }_x000D_
});

_x000D_

<script src="https://cdn.jsdelivr.net/npm/vue"></script>_x000D_
<section class="main-content">_x000D_
  <h1>{{ heading }}</h1>_x000D_
  <input type="number" v-on:change="updateCurrencies" v-model="usdamount">_x000D_
  <p class="cur-value" v-for="cur in currencies">_x000D_
    <strong>{{ cur.label }}</strong>: {{ cur.value }}_x000D_
  </p>_x000D_
</section>

_x000D_

_x000D_

_x000D_

Since you indeed have the case that data depends on usdamount and should be adjusted whenever that value changes, making currencies a computed property would be an even better approach:

_x000D_

_x000D_

var main = new Vue({_x000D_
  el: ".main-content",_x000D_
  data: {_x000D_
    heading: "First Vue Page",_x000D_
    usdamount: 0,_x000D_
_x000D_
  },_x000D_
  computed: {_x000D_
    currencies() {_x000D_
      let cur = [{_x000D_
          label: "GBP",_x000D_
          rate: 0.7214,_x000D_
          value: 0_x000D_
        },_x000D_
        {_x000D_
          label: "EUR",_x000D_
          rate: 0.80829,_x000D_
          value: 0_x000D_
        },_x000D_
        {_x000D_
          label: "CAD",_x000D_
          rate: 1.2948,_x000D_
          value: 0_x000D_
        }_x000D_
      ];_x000D_
      for (var i = cur.length - 1; i >= 0; i--) {_x000D_
        cur[i].value = cur[i].rate * parseFloat(this.usdamount);_x000D_
      }_x000D_
      return cur;_x000D_
    }_x000D_
_x000D_
  }_x000D_
});

_x000D_

<script src="https://cdn.jsdelivr.net/npm/vue"></script>_x000D_
<section class="main-content">_x000D_
  <h1>{{ heading }}</h1>_x000D_
  <input type="number" v-model="usdamount">_x000D_
  <p class="cur-value" v-for="cur in currencies">_x000D_
    <strong>{{ cur.label }}</strong>: {{ cur.value }}_x000D_
  </p>_x000D_
</section>

_x000D_

_x000D_

_x000D_

This way you don’t have to implement a listener yourself and instead use Vue’s mechanisms to update your data and DOM.

Leave a Reply

Your email address will not be published. Required fields are marked *