Reputation: 3411
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
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 primitiveForm
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
}
}
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