Vue Error in render: "RangeError: Invalid array length"

Ahmed Mamdouh picture Ahmed Mamdouh · Jul 20, 2018 · Viewed 8.5k times · Source

Vue: v2.*

In my project vuejs I use v-for range with computed

Computed

computed: {
   numberOfPages() {
         const result = Math.ceil(this.collection.total / this.collection.per_page)
         return (result < 1) ? 1 : result
    }
},

template

<li class="waves-effect" v-for="(number,index) in numberOfPages" 
    :key="index" :class="collection.current_page == number ? 'active' : ''"
     @click="currentPage(number)">
   <a class="">{{number}}</a>
</li>

Error Console

1 - [Vue warn]: Error in render: "RangeError: Invalid array length"

2 - RangeError: Invalid array length

Answer

Sumurai8 picture Sumurai8 · Jul 21, 2018

The most likely candidate for your problem is that your computed property returns NaN or Infinity. Without seeing all of your code, the most likely reason for that is one of the following:

  • You initialize collection to an empty Object. const result = Math.ceil(undefined / undefined) will return NaN
  • You do correctly prevent the property from being calculated before the result comes in, but the response from the server that populates collection has a per_page of 0. The calculation mentioned above would return Infinity, and Vue would not be able to create a range from that.

There are multiple ways of dealing with this problem. The easiest way is, if you can be certain that per_page is always > 0, to put a v-if on the element around your loop. If there is no convenient element, you can use the <template> element to put around it.

Otherwise you can check in your computed property if de data you are going to calculate with, is actually correct, and otherwise return a default number.

numberOfPages() {
  if (
    !this.collection ||
    Number.isNaN(parseInt(this.collection.total)) ||
    Number.isNaN(parseInt(this.collection.per_page)) ||
    this.collection.per_page <= 0
  ) {
    return 0;
  }

  const result = Math.ceil(this.collection.total / this.collection.per_page)
  return (result < 1) ? 1 : result
}