Bulent
Bulent

Reputation: 3411

Adding Input Value Into An Object (Vue.js)

I'm trying to create a table that contains a bunch of input text fields. My goal is to get the value of an input, and add it into an object with the row ID as the key. I tried to use v-model, but I lost. I actually managed to get all necessary pieces, but I couldn't put them together. So, I hope someone can help me on that.

Here is my input box:

<input
  type="text"
  :id="['tv_code_' + listItem.asset_id]"
  @input="getInputValue('tv_code', listItem.asset_id)"
>

The function:

getInputValue(obj, key) {
  var inputValue = document.getElementById(obj + "_" + key).value;
  if (inputValue.length > 0) { 
    this.$set(this.form.obj, key, inputValue);
  } else {
    this.$delete(this.form.obj, key);
  }
}

And vue.js data structure:

data(){
  form: new Form({
    tv_code: {}
  })
}

When I type something in the input, I'm getting these 3 errors:

[Vue warn]: Cannot set reactive property on undefined, null, or primitive value: undefined
[Vue warn]: Error in v-on handler: "TypeError: Cannot use 'in' operator to search for '1' in undefined"
TypeError: Cannot use 'in' operator to search for '1' in undefined

I don't understand what is undefined because when I try console log obj, key, and inputValue, I'm getting the correct values.

Upvotes: 1

Views: 3233

Answers (1)

tony19
tony19

Reputation: 138276

The error is related to Vue.set/this.$set, so the problem is likely on this line:

 this.$set(this.form.obj, key, inputValue)

It indicates that the first/target argument (i.e., this.form.obj) is either undefined, null, or a primitive (i.e., string, number, Symbol, boolean). Since this.form is declared as new Form(), the problem is likely inside the Form class (whose source is not posted in the question). Let's look at the three possibilities...

form.obj is undefined

  • Form does not declare obj

     class Form {
       constructor() {
         /* no obj anywhere */  // DON'T DO THIS
       }
     }
    
  • Form sets obj to undefined

     class Form {
       constructor() {
         this.obj = undefined;  // DON'T DO THIS
       }
     }
    

form.obj is null

  • Form sets obj to null

     class Form {
       constructor() {
         this.obj = null;      // DON'T DO THIS
       }
     }
    

form.obj is a primitive

  • Form sets obj to a value that is either string, number, symbol, or boolean

     class Form {
       constructor() {
         this.obj = 'foo';     // DON'T DO THIS
         this.obj = 1;         // DON'T DO THIS
         this.obj = Symbol();  // DON'T DO THIS
         this.obj = true;      // DON'T DO THIS
       }
     }
    

Solution

The fix would be to declare obj as an object:

class Form {
  constructor() {
    this.obj = { /*...*/ };
  }
}

class Form {
  constructor({ tv_code }) {
    this.tv_code = tv_code;
    this.obj = { foo: null };
  }
}

new Vue({
  el: "#app",
  data() {
    return {
      listItem: {
        asset_id: 'foo'
      },
      form: new Form({
        tv_code: {}
      }),
    };
  },
  methods: {
    getInputValue(obj, key) {
      const inputValue = document.getElementById(obj + "_" + key).value;
      if (inputValue.length > 0) {
        this.$set(this.form.obj, key, inputValue);
      } else {
        this.$delete(this.form.obj, key);
      }
    }
  }
});
<script src="https://unpkg.com/[email protected]"></script>

<div id="app">
  <input
  type="text"
  :id="['tv_code_' + listItem.asset_id]"
  @input="getInputValue('tv_code', listItem.asset_id)"
>
  <pre>{{form.obj}}</pre>
</div>

Upvotes: 1

Related Questions