1

I have a basic input that should update a data on input change, but it doesn't because it returns Uncaught TypeError: Cannot read property 'settings' of undefined

Vue component

<template>
    <div>
        <div class="inner_container">
          <p>
            URL:
            <span>{{settings.url}}</span>
          </p>
          <div class="input_row">
            <input
              class="input_text"
              id="getURL"
              type="url"
              inputmode="url"
              placeholder="Enter URL"
              title="URL"
              @input="changeUrl"
            />
            <label class="label_" for="getURL">URL Link</label>
          </div>
          <button class="button" @click="saveSettings">Save all Values</button>
        </div>
    <div>
</template>

<script>
import axios from "axios";
import _ from "lodash";

export default {
  name: "Home",
  data() {
    return {
      settings: {
        brightness: "",
      },
    };
  },
  methods: {
    changeUrl: _.debounce((e) => {
      this.settings.url = e.target.value;
    }, 500),
  },
};
</script>

On each input change I receive the above error.

What am I doing wrong ?

m02ph3u5
  • 2,735
  • 6
  • 34
  • 45
Jorje12
  • 343
  • 2
  • 10

3 Answers3

2

The problem is that this in the arrow function is not referring to the object you want. One solution is to use a normal function and predefine the property url in settings:

new Vue({
     el: '#app',
     data() {
          return {
               settings: {
                    brightness: "",
                    url: ""
               },
          };
     },
     methods: {
          changeUrl: _.debounce(function(e) { 
               this.settings.url = e.target.value; 
          }, 500),
          saveSettings(){
          
          }
     },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<div id="app">
     <div class="inner_container">
          <p>
               URL: <span>{{settings.url}}</span>
          </p>
          <div class="input_row">
               <input
                    class="input_text"
                    id="getURL"
                    type="url"
                    inputmode="url"
                    placeholder="Enter URL"
                    title="URL"
                    @input="changeUrl"
               />
               <label class="label_" for="getURL">URL Link</label>
          </div>
          <button class="button" @click="saveSettings">Save all Values</button>
     </div>
</div>

A simpler approach you may find useful is to set the variable using v-model:

new Vue({
     el: '#app',
     data() {
          return {
               settings: {
                    brightness: "",
               },
          };
     },
     methods: {
          saveSettings(){
          
          }
     },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<div id="app">
     <div class="inner_container">
          <p>
               URL: <span>{{settings.url}}</span>
          </p>
          <div class="input_row">
               <input
                    class="input_text"
                    id="getURL"
                    type="url"
                    inputmode="url"
                    placeholder="Enter URL"
                    title="URL"
                    v-model="settings.url"
               />
               <label class="label_" for="getURL">URL Link</label>
          </div>
          <button class="button" @click="saveSettings">Save all Values</button>
     </div>
</div>
Majed Badawi
  • 16,831
  • 3
  • 12
  • 27
  • 1
    I don't want to use `v-modal` because I don't want the input to visually change. I only want to take the input value, store it and send it through a `post` to be written in a file. The thing is that I forgot that `this` doesn't work inside an arrow function. – Jorje12 Aug 03 '20 at 11:26
  • Why does `this` work inside an axios handler like: ```server .post("/dhcpWifi", data) .then(function(res) { if (res.status == 200) { this.message = "Settings have been saved."; } else { this.message = "Something went wrong. Please try again"; } }) .catch((err) => { console.log(err); this.message = ""; });``` Why isn't `this.message` also undefined ? Why does it work here ? – Jorje12 Aug 03 '20 at 18:20
1

Ciao, try to use debounce like this:

_.debounce(function(e) {
  this.settings.url = e.target.value;
}, 500)
Giovanni Esposito
  • 5,165
  • 1
  • 5
  • 23
1

The problem is that you are using this in a statement that is not being called on a JS class. Fix this by changing the this to a variable name, and setting that variable name to a class.

cs1349459
  • 452
  • 6
  • 20