I have a pretty simple sort going on but I'm getting this error:
[Vue warn]: You may have an infinite update loop for watcher with expression: items
Any advice? Am I doing anything funky? Here's the code that's throwing it.
var sorts = {
foo: [8, 6, 5, 2, 1, 3, 4, 7, 10, 9],
bar: [8, 6, 5, 2, 10, 9, 1, 3, 4, 7],
baz: [10, 8, 6, 5, 2, 9, 1, 3, 4, 7]
};
new Vue({
el: '#app',
data: {
category: 'foo',
items: [
{ id: 1, name: 'One' },
{ id: 2, name: 'Two' },
{ id: 3, name: 'Three' },
{ id: 4, name: 'Four' },
{ id: 5, name: 'Five' },
{ id: 6, name: 'Six' },
{ id: 7, name: 'Seven' },
{ id: 8, name: 'Eight' },
{ id: 9, name: 'Nine' },
{ id: 10, name: 'Ten' }
]
},
filters: {
sortByCategory: function (values, category) {
var sortOrder = sorts[category];
return values.sort(function (a, b) {
a = sortOrder.indexOf(a.id);
b = sortOrder.indexOf(b.id);
return a - b;
});
}
}
});
along with a demo: http://jsbin.com/ximoqumazi/1/edit?js,output
You are indeed causing an infinite loop, because array.sort()
mutates the array itself, which triggers the filter to be applied again. Make sure to sort on a copy:
return values.slice().sort(...)
Perfect. Thanks, Evan!
perfect,Even!!!
I just lost a few hours by a similar in place array mutation. In my case I used the Array.prototype.reverse()
function in the template.
I mention it here, so maybe this can help other developers.
I used the following code in a template that produced the same infinite loop warning:
<div v-for="tel in telephoneNumbers.reverse()">
{{tel}}
</div>
Lesson learned: Prepare / mutate data before adding it to the local component state.
Most helpful comment
You are indeed causing an infinite loop, because
array.sort()
mutates the array itself, which triggers the filter to be applied again. Make sure to sort on a copy: