1

I am trying to increment an array value when I add a new row in Vue.js, but I get the error:

You may have an infinite update loop in a component render function.

The JavaScript:

new Vue({
  el: '#app',
  data: () => ({
    inputs: [{
      id: 0,
      username: ''
    }],
  }),
  methods: {
    add() {
      this.inputs.push({ id: this.id++, username: '' });
    }
  }
});

The markup:

<div id="app">
  <div v-for="input in inputs">
    <input :key="input.id" :name="'username_' + input.id" type="text" v- v-model="input.username" placeholder="username">
  </div>
  <button @click="add">Add</button>
</div>

However, if I hardcode the value in the add function it works the first time:

add() {
  this.inputs.push({ id: 1, username: '' });
}

So, how can I make it dynamic? Typing id: this.id++ does not work.

2 Answers 2

8

The problem :- this.id is undefined Vue doesn't know id because its not in the component data

so you have to options to solve your problem

  • define the varaible id like this

    data(){
         id:0,inputs:[]
     }
    
  • other option which will solve the problem and I prefer it is to replace this line of code

        this.inputs.push({ id: this.id++, username: '' });
    

    with this line

      this.inputs.push({ id: this.inputs.length, username: '' });
    

    this will solve the problem and here is the compelete code

new Vue({
    el: '#app',
  data: () => ({
    inputs: [{
   id: 0,
   username: ''
}],
  }),
  methods: {
    add () {
      console.log(this.inputs.length);
      this.inputs.push({ id: this.inputs.length, username: '' });
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

  <div id="app">
    <div v-for="input in inputs">
      <input :key="input.id" :name="'username_' + input.id" type="text" v- v-model="input.username" placeholder="username">
    </div>
    <button @click="add">Add</button>
  </div>

Sign up to request clarification or add additional context in comments.

1 Comment

Had no clue I could use this.inputs.length like that, thought it would only output the current value, but I guess the object gets pushed into the array before that line runs?
0

Even more simply:

Using the index. Work for me.

Enjoy!

new Vue({
    el: '#app',
  data: () => ({
    inputs: [{
   username: ''
}],
  }),
  methods: {
    add () {
      this.inputs.push({ username: '' });
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

  <div id="app">
    <div v-for="(input, index) in inputs">
      <input :name="'username_' + index" type="text" v-model="input.username" placeholder="username">
    </div>
    <button @click="add">Add</button>
  </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.