vue-good-table icon indicating copy to clipboard operation
vue-good-table copied to clipboard

RangeError: Maximum call stack size exceeded

Open hanouard opened this issue 3 years ago • 1 comments

Issue Type (delete the irrelevant ones)

  • [x] Bug

Specs

What version are you using? v2.21.11

What browser? Chrome

Expected Behavior

What did you expect to happen? to work

Actual Behavior

What actually happened?

RangeError: Maximum call stack size exceeded
    at eval (vue-good-table.esm.js?f617:9028)
    at Array.forEach (<anonymous>)
    at VueComponent.paginated (vue-good-table.esm.js?f617:9020)
    at Watcher.get (vue.runtime.esm.js?2b0e:4495)
    at Watcher.evaluate (vue.runtime.esm.js?2b0e:4597)
    at VueComponent.computedGetter [as paginated] (vue.runtime.esm.js?2b0e:4851)
    at VueComponent.selectedPageRows (vue-good-table.esm.js?f617:8797)
    at Watcher.get (vue.runtime.esm.js?2b0e:4495)
    at Watcher.evaluate (vue.runtime.esm.js?2b0e:4597)
    at VueComponent.computedGetter [as selectedPageRows] (vue.runtime.esm.js?2b0e:4851)

Steps to Reproduce the Problem

<template>
  <div>
    <vue-good-table
        :columns="columns"
        :rows="rows"
        :pagination-options="{
          enabled: true,
          mode: 'records',
          perPage: 5,
          position: 'top'
        }"
    />
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  created() {
    console.time('preparing rows');
    for(let index=0; index < 400001; index+=6) {
      this.rows.push({id: 1+index, name: "John"+index, age: 20, createdAt: '2000-01-31', score: 0.03343},
          {id: 2+index, name: "Jane"+index, age: 24, createdAt: '2011-10-31', score: 0.03343},
          {id: 3+index, name: "Susan"+index, age: 16, createdAt: '2011-10-30', score: 0.03343},
          {id: 4+index, name: "Chris"+index, age: 55, createdAt: '2011-10-11', score: 0.03343},
          {id: 5+index, name: "Dan"+index, age: 40, createdAt: '2011-10-21', score: 0.03343},
          {id: 6+index, name: "John"+index, age: 20, createdAt: '2011-10-31', score: 0.03343});
    }
    console.timeEnd('preparing rows');
  },
  data() {
    return {
      columns: [
        {
          label: 'Name',
          field: 'name',
        },
        {
          label: 'Age',
          field: 'age',
          type: 'number',
        },
        {
          label: 'Created On',
          field: 'createdAt',
          type: 'date',
          dateInputFormat: 'yyyy-MM-dd',
          dateOutputFormat: 'MMM do yy',
        },
        {
          label: 'Percent',
          field: 'score',
          type: 'percentage',
        },
      ],
      rows: [],
    };
  },
}
</script>

It looks like it's processing the whole pages instead of the selected page.

hanouard avatar Nov 19 '21 13:11 hanouard

If you need to deal with 400,000+ rows of data, I would recommend using a database that handles pagination (limit/offset), and then using the "remote" features of Vue-Good-Table to only load 100 items into the table at a time. That's just a ton of data to store reactively in memory. Your example would generate ~32MB of JSON, then you factor in all of Vue's reactivity and it gets a lot more expensive for a browser tab to deal with.

Alternatively, you could cycle through the chunks of data you are passing in to the table, rather than passing in the entire array, just pass in a subset of it. This could also be done via the remote mode of VGT, but instead of hitting a network request, you run a function to grab the next chunk of data (or dynamically generate it, like you are here)

TheJaredWilcurt avatar Jan 26 '22 17:01 TheJaredWilcurt