Search code examples
vue.jschart.jsvue-chartjs

[Vue warn]: You may have an infinite update loop in watcher with expression "chartData"


Below is a copy of my vue file with the watcher mentioned in the warning:

<script>
  import { Radar } from 'vue-chartjs'

  export default {
    extends: Radar,
    props:['chartData','options'],
    mounted () {
      this.renderChart(this.chartData, this.options)
    },
    watch: {
      chartData: {
        handler: function(newVal, oldVal) {
          this.$data._chart.update()
        },
        deep: true
      }
    }
  }
</script>

I don't see anything wrong with the code and don't know why it is causing a loop. Any help would be appreciated. I am passing in chartData via props. If you need anything else, please let me know.

To try to make things easier, below is how I am passing in the prop chartData:

<caChampions :chartData="dataForLChampions" :options="optionsForLChampions" />

This data is updated every time someone selects something from a drop-down. The code from the drop-down is below:

<v-autocomplete
                label="Champion"
                placeholder="Enter Champion's Name Here"
                :loading="championSelectLoading"
                v-model="selectedChampion"
                @input="getChampionInfo()"
                :items="champions"
                autocomplete
                autofocus
                outline
                full-width
                ></v-autocomplete>

The first time someone selects something, it works great. However, the second selection on creates a loop and I am not sure why.


Solution

  • You should use reactiveProp mixin instead of update chart yourself.

    In document, it said:

    On data change, it will either call update() if only the data inside the datasets has changed or renderChart() if new datasets were added.

    <script>
      import { Radar, mixins } from 'vue-chartjs'
    
      export default {
        extends: Radar,
        props:['chartData','options'],
        mixins: [mixins.reactiveProp],
        mounted () {
          this.renderChart(this.chartData, this.options)
        }
      }
    </script>