1
votes

I have an error in the console when I try to sort an array in ascending or descending order.

I'm using Vue to make an ordered table, and I can do a table with the data already have. But when I call a function, I take a correct result display in my page but have an error in the console. When I try to make some code to return the %10 of all array, like var i = array.lenght * 0-1" it doesnt work.

<tbody id="app" v-bind:placeholder="OrdenarMiembrosDesc(members)" required>
    <tr v-for="member in members">
    <td>{{ member.first_name }} {{member.last_name}}</td>
    <td>{{ member.total_votes }}</td>
    <td>{{ member.votes_with_party_pct }} </td>
    </tr>
</tbody>
<script>

let app = new Vue({
    el: '#app',
    data: {
        members: [] //this already have a lot of users info, and it works
    },
    methods: {
        OrdenarMiembrosAsc(miembros) {
            return miembros.sort((a, b) => (a.votes_with_party_pct > b.votes_with_party_pct) ? 1 : -1);
        },

        OrdenarMiembrosDesc: function(miembros) {
            var temp = miembros.sort((a, b) => (a.votes_with_party_pct < b.votes_with_party_pct) ? 1 : -1);
            var i = temp.lenght;
            console.log(temp);
            console.log(i);
            return temp;
        },
    }
});

</script>

I expect no messages except the log of my variable, but I have a lot of console logs and then "[Vue warn]: You may have an infinite update loop in a component render function.

(found in )"

1

1 Answers

0
votes

Any methods that are called during a render (i.e. method calls in your template) should not mutate reactive state because this will trigger potentially infinite re-renders, hence the warning.

members is reactive state, and you are calling members.sort() which mutates the array instead of returning a new array.

Simple fix is to .slice() it first. This performs a shallow clone of the array.

var temp = miembros
  .slice()
  .sort((a, b) => (a.votes_with_party_pct < b.votes_with_party_pct) ? 1 : -1);

Even better is to define these as computed properties instead of methods since there's no reason for them to be methods and you get the benefit of caching the result for improved performance.

computed: {
  OrdenarMiembrosAsc() {
    return this.members
      .slice()
      .sort((a, b) => (a.votes_with_party_pct > b.votes_with_party_pct) ? 1 : -1);
  },

  OrdenarMiembrosDesc() {
    return this.members
      .slice()
      .sort((a, b) => (a.votes_with_party_pct < b.votes_with_party_pct) ? 1 : -1);
  }
}