I am getting the following infinite loop warning. I understand that it is probably because I am changing a variable in my template's for loop due to a method call. Any idea how to fix it? The loop does plete, so it's not actually an infinite loop, but I'd like to fix the warning.
[Vue warn]: You may have an infinite update loop in a ponent render function.
Code Snippet:
new Vue({
el: '#app',
data: {
contents: {"34": {"id": 34, build_name: "email_simple", build_readable: "Email"},"35": {"id": 35, build_name: "email_plex", build_readable: "Email"},"36": {"id": 36, build_name: "email_half", build_readable: "Email"}},
last_build_type: '',
contents_tree: [34,35,36]
},
methods: {
checkBuildType(id){
let check = false;
if(this.last_build_type !== this.contents[id].build_name){
check = true
}
this.last_build_type = this.contents[id].build_name;
return check
}
}
})
<script src=".5.17/vue.js"></script>
<div id="app">
<template v-for="(id, i) in contents_tree">
<div v-bind:key="i + '_' + id" class="inline">
<template v-if="checkBuildType(id)">
{{i}} - {{id}} -
{{contents[id].build_readable}}
<br>
</template>
</div>
</template>
</div>
I am getting the following infinite loop warning. I understand that it is probably because I am changing a variable in my template's for loop due to a method call. Any idea how to fix it? The loop does plete, so it's not actually an infinite loop, but I'd like to fix the warning.
[Vue warn]: You may have an infinite update loop in a ponent render function.
Code Snippet:
new Vue({
el: '#app',
data: {
contents: {"34": {"id": 34, build_name: "email_simple", build_readable: "Email"},"35": {"id": 35, build_name: "email_plex", build_readable: "Email"},"36": {"id": 36, build_name: "email_half", build_readable: "Email"}},
last_build_type: '',
contents_tree: [34,35,36]
},
methods: {
checkBuildType(id){
let check = false;
if(this.last_build_type !== this.contents[id].build_name){
check = true
}
this.last_build_type = this.contents[id].build_name;
return check
}
}
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template v-for="(id, i) in contents_tree">
<div v-bind:key="i + '_' + id" class="inline">
<template v-if="checkBuildType(id)">
{{i}} - {{id}} -
{{contents[id].build_readable}}
<br>
</template>
</div>
</template>
</div>
Share
edited Mar 25, 2020 at 15:25
AlexMA
10.2k7 gold badges45 silver badges66 bronze badges
asked Mar 25, 2020 at 12:34
JordanJordan
1,6522 gold badges17 silver badges27 bronze badges
10
-
what is
contents_tree
? I believe we need more code to see what is actually causing the error – depperm Commented Mar 25, 2020 at 12:35 - i think checkBuildType will alwayse returns true because new build would be different from current if i'm understanding your code correctly. – Harsh Srivastava Commented Mar 25, 2020 at 12:39
-
@depperm I have added an example
contents_tree
and an examplecontents
. – Jordan Commented Mar 25, 2020 at 12:41 - 1 Happy to help but please provide a runnable codepen or other plete snippet that reproduces the bug.stackoverflow./help/minimal-reproducible-example – AlexMA Commented Mar 25, 2020 at 12:53
- 2 @AlexMA I have added the code snippet which is generating the error. – Jordan Commented Mar 25, 2020 at 13:16
1 Answer
Reset to default 4You are getting that warning because Vue has to re-render for each item in the v-for
loop, due to the fact that the for loop updates the ponent's state. My solution is to pute the result for each array item in one pass, in a puted property (basically an index object), and access that puted property in the v-for
rather than using the checkBuildType
method.
new Vue({
el: '#app',
data: {
contents: {
"33": {
"id": 33,
build_name: "email_half",
build_readable: "Email"
},
"34": {
"id": 34,
build_name: "email_simple",
build_readable: "Email"
},
"35": {
"id": 35,
build_name: "email_plex",
build_readable: "Email"
},
"36": {
"id": 36,
build_name: "email_half",
build_readable: "Email"
},
"37": {
"id": 37,
build_name: "email_half",
build_readable: "Email"
}
},
last_build_type: '',
contents_tree: [34, 35, 36, 37, 33]
},
puted: {
buildTypes() {
const buildTypesMap = {};
for (id of this.contents_tree) {
buildTypesMap[id] = this.checkBuildType(id);
}
return buildTypesMap
}
},
methods: {
checkBuildType(id) {
let check = false;
if (this.last_build_type !== this.contents[id].build_name) {
check = true
}
this.last_build_type = this.contents[id].build_name;
return check
}
}
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template v-for="(id, i) in contents_tree">
<div v-bind:key="i + '_' + id" class="inline">
<template v-if="buildTypes[id]">
{{i}} - {{id}} -
{{contents[id].build_readable}}
<br>
</template>
</div>
</template>
</div>