Vuetify v-select dynamically populate/sort

Total
11
Shares

I am trying to dynamically populate and sort an array used by v-select. However I am coming across the es-lint warning ‘unexpected side-effect in computed property’, because I am mutating objects in that call. Is there a more appropriate pattern for appending new data to an array and sorting it? Here is some quick & dirty skeleton code to get the gist across

// SomeFile.vue
<MySelectComponent :someData="changingArray" />

// MySelectComponent.vue
<v-select v-model="selectedItems" :items="mergeWithNewData" >
...

props: { 
  someData: Array,
},
data: () => ({
  selectedItems: [],
  holdsEverything: [],
},
computed: {
  mergeWithNewData() {
    this.someData.forEach(item => {
      if (!this.holdsEverything.includes(item)){
        this.holdsEverything.push(item);
        this.holdsEverything.sort();
      }
    });
    return this.holdsEverything;
  },
}

As an example, Let’s say changingArray starts as [‘a’,’b’,’c’]. As the code is running changingArray is now [‘b’,’z’]. holdsEverything should be [‘a’,’b’,’c’,’z’]


Solution

Looks like you want the sorted distinct values from someData. There’s no need to push data to another array when using computed, just return the calculated results as follows:

computed: {
  mergeWithNewData () {
    return [...new Set(this.someData)].sort()
  }
}

Or use watch instead of computed:

<v-select v-model="selectedItems" :items="holdsEverything" >  
// use holdsEverthing directly

watch: {
  someData (newval) {
    newval.forEach(item => {
      if (!this.holdsEverything.includes(item)){
        this.holdsEverything.push(item)
      }
    })
    this.holdsEverything.sort()
  }
}
Leave a Reply

Your email address will not be published. Required fields are marked *